我在让托尔这么做时遇到了一些麻烦,所以希望有人可以指出我做错了什么.
我有一个主类class MyApp < Thor
,我想分成多个名称空间的单独文件,比如thor create:app_type
和thor update:app_type
.我找不到任何一个例子来说明如何将Thor应用程序拆分成碎片,而我尝试过的东西似乎不起作用.
举个例子,这个班我试图从主要的Thor类中脱颖而出:
module Things
module Grouping
desc "something", "Do something cool in this group"
def something
....
end
end
end
Run Code Online (Sandbox Code Playgroud)
当我尝试在我的主要课程中包含或要求时:
class App < Thor
....
require 'grouping_file'
include Things::Grouping
....
end
Run Code Online (Sandbox Code Playgroud)
我得到一个例外: '<module:Grouping>': undefined method 'desc' for Things::Grouping:Module (NoMethodError)
是否有可能为Thor任务设置多个名称空间,如果是,那么如何将其分解出来以便您没有一个需要几百行的单一类?
Ric*_*ruz 13
为什么它不起作用:当你desc
在Thor
类中使用时,实际上是在调用类方法Thor.desc
.当你在模块中执行此操作时,它会调用YourModule.desc
显然不存在的模块.
我可以通过两种方式来解决这个问题.
您是否希望在多个Thor课程中重复使用这些任务?
当模块用作include
Ruby时,included
调用类方法.http://www.ruby-doc.org/core/classes/Module.html#M000458
module MyModule
def self.included(thor)
thor.class_eval do
desc "Something", "Something cool"
def something
# ...
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
您是否只想在另一个文件中单独定义任务?
如果是这样,只需在另一个文件中重新打开App类.你的Thorfile看起来像:
# Thorfile
Dir['./lib/thor/**/*.rb'].sort.each { |f| load f }
Run Code Online (Sandbox Code Playgroud)
然后你lib/thor/app.rb
将包含一些任务App
,而另一个文件lib/thor/app-grouping.rb
将包含同一个App
类的更多任务.
sem*_*ros 13
使用一个覆盖模块,比方说Foo
,您将在其中定义所有子模块和子类.
在单个foo.thor
文件中启动此模块的定义,该文件位于运行所有Thor任务的目录中.在此Foo
模块的顶部foo.thor
,定义此方法:
# Load all our thor files
module Foo
def self.load_thorfiles(dir)
Dir.chdir(dir) do
thor_files = Dir.glob('**/*.thor').delete_if { |x| not File.file?(x) }
thor_files.each do |f|
Thor::Util.load_thorfile(f)
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
然后在主foo.thor
文件的底部添加:
Foo.load_thorfiles('directory_a')
Foo.load_thorfiles('directory_b')
Run Code Online (Sandbox Code Playgroud)
这将以递归方式包含*.thor
这些目录中的所有文件.在主Foo
模块中嵌套模块以命名您的任务.只要您通过上述方法包含所有与Thor相关的目录,无论文件位于何处或在此处调用它们都无关紧要.
小智 5
我也遇到了同样的问题,几乎要放弃了,但后来我有了一个想法:
如果您将任务写入Thorfile
s 而不是作为 ruby 类,那么您可以简单地require
在包含 Thor 子类的 Ruby 文件中,并且当您运行时它们将出现在可用任务列表中thor -T
。
这一切都是班级管理的Thor::Runner
。如果您仔细查看此内容,您将看到一个#thorfiles
负责查找Thorfile
当前工作目录下命名的文件的方法。
我所要做的就是 a) 将我的 Thor 任务分解为多个文件,同时 b) 不必Thorfile
创建一个 的本地子类Thor::Runner
,#thorfile
用返回我的应用程序特定的 Thor 任务文件列表的方法覆盖其方法,然后调用它的#start
方法和一切都有效:
class MyApp::Runner < ::Thor::Runner
private
def thorfiles(*args)
Dir['thortasks/**/*.rb']
end
end
MyApp::Runner.start
Run Code Online (Sandbox Code Playgroud)
所以我可以有任意数量的 Ruby 类定义 Thor 任务,thortasks
例如
class MyApp::MyThorNamespace < ::Thor
namespace :mynamespace
# Unless you include the namespace in the task name the -T task list
# will list everything under the top-level namespace
# (which I think is a bug in Thor)
desc "#{namespace}:task", "Does something"
def task
# do something
end
end
Run Code Online (Sandbox Code Playgroud)
在我弄清楚这一点之前,我几乎放弃了 Thor,但是没有很多库可以处理创建生成器以及构建命名空间任务,所以我很高兴找到了一个解决方案。
归档时间: |
|
查看次数: |
7282 次 |
最近记录: |