[英]How do I use Thor actions without requiring a Thor CLI app?
Thor :: Actions( http://textmate.rubyforge.org/thor/Thor/Actions.html )有一些很棒的幫助方法我想訪問但是如果不使用Thor CLI應用程序我似乎無法使用它們。
我試過簡單地說:
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)
我意識到我可能會遺漏一些非常簡單的東西。 謝謝。
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在其包含器上定義類方法(而不是實例方法)。
舉個例子,
[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__'
但是如果你ClassMethod
Klass
並include Klass::Mod
那么included
回調會extends
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
這花了我一段時間才弄清楚,所以不要感覺不好,不要,它不是那么簡單或明顯。
要在不繼承Thor
情況下使用Thor::Actions
:
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
編輯:如果要控制創建文件和文件夾的位置,則需要設置destination_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
我自己是Thor的新手,但我不認為它是獨立工作的。
嘗試在內部創建Thor任務,然后啟動它。
這是我嘗試過的一個例子,放在一個名為thor_createfile.rb
的文件中(我已經添加了一些其他的東西,我將在代碼之后解釋,這可能對你很有啟發性):
#!/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
方法。
現在你應該能夠像這樣簡單地調用它:
./thor_createfile.rb
它將使用指定為default_task
的任務。
但是,如果需要使用某些命令行參數,則可以按名稱顯式調用任務。 所以要調用其他任務,例如:
./thor_createfile.rb createFile fancy_file_name.txt "Text to go inside the file"
注意我告訴它include Thor::Actions
所以你感興趣的所有項目(比如create_file
)都可用。
現在你可以在其中添加其他任務(確保為每個任務添加desc
,否則它可能會抱怨)並根據需要使用它們。
要讓它告訴你里面定義的所有任務,你可以這樣調用它:
./thor_createfile.rb -?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.