Ruby 如何在不需要Thor CLI应用程序的情况下使用Thor操作?

Ruby 如何在不需要Thor CLI应用程序的情况下使用Thor操作?,ruby,thor,Ruby,Thor,我想访问Thor::Actions()中的一些很棒的助手方法,但如果不使用Thor CLI应用程序,我似乎无法使用它们 我只是试过: require "rubygems" require "thor" Thor::Actions.create_file "foo.txt", "contents" 它抛出: run.rb:4:in'':为Thor::Actions:Module(NoMethodError)未定义的方法“创建文件” 我意识到我可能错过了一些非常简单的东西。谢谢。我自己对托尔来说

我想访问Thor::Actions()中的一些很棒的助手方法,但如果不使用Thor CLI应用程序,我似乎无法使用它们

我只是试过:

require "rubygems"
require "thor"

Thor::Actions.create_file "foo.txt", "contents"
它抛出:

run.rb:4:in'':为Thor::Actions:Module(NoMethodError)未定义的方法“创建文件”


我意识到我可能错过了一些非常简单的东西。谢谢。

我自己对托尔来说是新手,但我认为它不适合独立工作

尝试在内部创建一个Thor任务,然后启动它

下面是我尝试过的一个示例,并将其放在一个名为
thor_createfile.rb
的文件中(我在代码之后添加了一些其他内容,我将解释这些内容,这可能会对您有所启发):

它将使用指定为
default\u task
的任务

但是,如果需要获取一些命令行参数,可以显式地按名称调用任务。因此,要调用其他任务,例如:

./thor_createfile.rb createFile fancy_file_name.txt "Text to go inside the file"
注意,我已经告诉它要
包含Thor::Actions
,这样您感兴趣的所有项目(如
创建\u文件
)都可以使用

现在,您可以在其中添加其他任务(确保为每个任务添加
desc
,否则它可能会抱怨),并根据需要使用这些任务

要让它告诉您其中定义的所有任务,您可以这样称呼它:

./thor_createfile.rb -?

Thor打算让您的类成为Thor类的子类。然后,Thor类包含并扩展模块,使其方法成为类方法。如果您查看源代码,例如
Actions.rb
,您将了解我的意思:

# thor/lib/thor/actions.rb

class Thor
  module Actions

    # this is the interesting part and answers your question
    def self.included(base) #:nodoc:
      base.extend ClassMethods
    end

    module ClassMethods
这是一种常见的Ruby习惯用法,它使用mixin在其inclusor上定义类方法(而不是实例方法)

例如,

[2] pry(main)> class Klass
[2] pry(main)*   module Mod  
[2] pry(main)*     def self.included(base)    
[2] pry(main)*       base.extend ClassMethods      
[2] pry(main)*     end  
[2] pry(main)*     module ClassMethods    
[2] pry(main)*       def act_as_class_method      
[2] pry(main)*         puts "Im a class method now!!!"        
[2] pry(main)*       end  
[2] pry(main)*     end  
[2] pry(main)*   end  
[2] pry(main)* end  
=> nil
现在呼叫

Klass::Mod.act_as_class_method
结果与您的错误相同

NoMethodError: undefined method `act_as_class_method' for Klass::Mod:Module
from (pry):26:in `__pry__'
但是,如果您对
klas
include-klas::Mod
进行子类化,则
include
回调
扩展了
ClassMethod
模块,允许您将
ClassMethods
中定义的方法用作类方法

[4] pry(main)> class Example < Klass
[4] pry(main)*   include Klass::Mod

[4] pry(main)*   self.act_as_class_method
[4] pry(main)* end  

=> Im a class method now!!!
=> nil
[4]撬(主)>类示例我现在是一个类方法!!!
=>零

一开始我花了一段时间才弄明白,所以别难过,不,这不是那么简单或明显

使用
Thor::Actions
而不继承
Thor

class Builder # or whatever
  # To get your hands on the `from_superclass` method
  include Thor::Base

  # What we're interested in…
  include Thor::Actions
  source_root "/path/to/where/things/come/out"

  def initialize(*)
    # whatever you might want to do
    @destination_stack = [self.class.source_root]
  end
end
希望其他人觉得这个有用。使用Thor v0.18.1进行试验和测试;由于这是内部API的东西,它可能会在将来的某个时候崩溃

然后可以在
Builder
类中使用帮助器方法,如下所示:

class Builder
  def build
    in_root { 'do things' }
    create_file 'etc'
  end
end
编辑:如果要控制文件和文件夹的创建位置,需要设置
目的地\u root
如下:

class Builder
  include Thor::Base
  include Thor::Actions
  source_root Dir.pwd

  def initialize(root)
    self.destination_root = File.expand_path(root)
  end

  def build
    directory 'templates', 'target'
  end
end

只是一个很小的风格点……在大多数Ruby代码中,您会发现使用snake-case的方法。
class Builder
  def build
    in_root { 'do things' }
    create_file 'etc'
  end
end
class Builder
  include Thor::Base
  include Thor::Actions
  source_root Dir.pwd

  def initialize(root)
    self.destination_root = File.expand_path(root)
  end

  def build
    directory 'templates', 'target'
  end
end