首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在不需要Thor CLI应用的情况下使用Thor actions?

如何在不需要Thor CLI应用的情况下使用Thor actions?
EN

Stack Overflow用户
提问于 2013-06-27 07:43:22
回答 3查看 2K关注 0票数 4

我想要访问来自Thor::Actions (http://textmate.rubyforge.org/thor/Thor/Actions.html)的一些很棒的助手方法,但如果不使用Thor CLI应用程序,我似乎无法使用它们。

我已经简单地尝试了:

代码语言:javascript
复制
require "rubygems"
require "thor"

Thor::Actions.create_file "foo.txt", "contents"

这会抛出:

run.rb:4:in '<main>': undefined method 'create_file' for Thor::Actions:Module (NoMethodError)

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

EN

回答 3

Stack Overflow用户

发布于 2013-07-25 12:59:31

雷神打算让你的类成为雷神的子类。然后,Thor类包含并扩展模块,允许它们的方法成为类方法。如果你看一下源代码,例如Actions.rb,你就会明白我的意思:

代码语言:javascript
复制
# 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在其包含函数上定义类方法(而不是实例方法)。

举个例子,

代码语言:javascript
复制
[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

现在呼叫

代码语言:javascript
复制
Klass::Mod.act_as_class_method

会导致与您相同的错误

代码语言:javascript
复制
NoMethodError: undefined method `act_as_class_method' for Klass::Mod:Module
from (pry):26:in `__pry__'

但是,如果您子类化Klassinclude Klass::Mod included回调extends ClassMethod模块,则允许您使用在ClassMethods中定义的方法作为类方法

代码语言:javascript
复制
[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

一开始我花了一段时间才弄明白,所以不要感觉不好,不,这不是那么简单或明显。

票数 5
EN

Stack Overflow用户

发布于 2013-11-10 09:26:30

使用不继承ThorThor::Actions

代码语言:javascript
复制
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类中使用助手方法,如下所示:

代码语言:javascript
复制
class Builder
  def build
    in_root { 'do things' }
    create_file 'etc'
  end
end

编辑:如果你想控制你创建文件和文件夹的位置,你需要像这样设置destination_root

代码语言:javascript
复制
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
票数 5
EN

Stack Overflow用户

发布于 2013-07-01 04:15:20

我自己也是雷神的新手,但我不认为它是为了独立工作而设置的。

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

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

代码语言:javascript
复制
#!/usr/bin/env ruby

require 'rubygems'    
require 'thor'

class MyThorTasks < Thor
  include Thor::Actions

  default_task :createInflexibleFile

  desc "createFile <fname> <content>", "Creates a file with some content"
  def createFile(fname, content)
    create_file fname, content
  end

  INFLEXIBLE_FILENAME = "the_filename.txt"
  INFLEXIBLE_CONTENT = "Greetings, Earthlings!"

  desc "createInflexibleFile", "Creates a file called '#{INFLEXIBLE_FILENAME}' containing '#{INFLEXIBLE_CONTENT}'"
  def createInflexibleFile
    puts "Creating a file called '#{INFLEXIBLE_FILENAME}' containing '#{INFLEXIBLE_CONTENT}'"
    create_file INFLEXIBLE_FILENAME, INFLEXIBLE_CONTENT
  end
end

MyThorTasks.start

您可以看到它定义了一个扩展Thor的类,然后对其调用start方法。

现在你应该可以像这样简单地调用它:

代码语言:javascript
复制
./thor_createfile.rb

它将使用指定为default_task的任务。

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

代码语言:javascript
复制
./thor_createfile.rb createFile fancy_file_name.txt "Text to go inside the file"

注意:我已经告诉了include Thor::Actions,所以你感兴趣的所有项目(比如create_file)都是可用的。

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

要让它告诉您它内部定义的所有任务,您可以这样调用它:

代码语言:javascript
复制
./thor_createfile.rb -?
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17332255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档