在尝试开发一个简单的宝石来学习这个过程时,我偶然发现了这个问题: Thor DSL将选项带入命令使用语法:option :some_option, :type => :boolean
,就在方法定义之前。
我正在尝试从文件中加载一组动态选项。我在构造函数中执行此文件读取操作,但似乎 Thor 类的option
关键字在initialize
方法之前得到处理。
有什么想法来解决这个问题?如果有人可以解释选项关键字如何工作,那也很棒?我的意思是option
方法调用?我没有得到设计。 (这是我尝试的第一个DSL,并且是Ruby Gems的新手)
#!/usr/bin/env ruby
require 'thor'
require 'yaml'
require 'tinynews'
class TinyNewsCLI < Thor
attr_reader :sources
@sources = {}
def initialize *args
super
f = File.open( "sources.yml", "r" ).read
@sources = YAML::load( f )
end
desc "list", "Lists the available news feeds."
def list
puts "List of news feed sources: "
@sources.each do |symbol, source|
puts "- #{source[:title]}"
end
end
desc "show --source SOURCE", "Show news from SOURCE feed"
option :source, :required => true
def show
if options[:source]
TinyNews.print_to_cli( options[:source].to_sym )
end
end
desc "tinynews --NEWS_SOURCE", "Show news for NEWS_SOURCE"
@sources.keys.each do |source_symbol| # ERROR: States that @sources.keys is nil
#[:hindu, :cnn, :bbc].each do |source_symbol| # I expected the above to work like this
option source_symbol, :type => :boolean
end
def news_from_option
p @sources.keys
TinyNews.print_to_cli( options.keys.last.to_sym )
end
default_task :news_from_option
end
TinyNewsCLI.start( ARGV )
答案 0 :(得分:4)
经过一些调整后,我认为我找到了一个看起来不太糟糕的解决方案。但不确定将代码放在模块中是不是一个好习惯。但无论如何:
#!/usr/bin/env ruby
require 'thor'
require 'yaml'
require 'tinynews'
module TinyNews
# ***** SOLUTION *******
f = File.open( "../sources.yml", "r" ).read
SOURCES = YAML::load( f )
class TinyNewsCLI < Thor
default_task :news_from_source
desc "list", "Lists the available news feeds."
def list
puts "List of news feed sources: "
SOURCES.each do |symbol, source|
puts "- #{source[:title]}"
end
end
desc "--source NEWS_SOURCE", "Show news for NEWS_SOURCE"
option :source, :required => true, :aliases => :s
def news_from_source
TinyNews.print_to_cli( options[:source].to_sym )
end
end
end
TinyNews::TinyNewsCLI.start( ARGV )