【问题标题】:Dynamically loading Thor options for a Ruby Gem为 Ruby Gem 动态加载 Thor 选项
【发布时间】:2014-03-30 08:56:51
【问题描述】:

在尝试开发一个简单的 gem 来学习这个过程时,我偶然发现了这个问题:Thor DSL 将 options 引入到一个 command em> 使用语法:option :some_option, :type => :boolean,就在方法定义之前。

我正在尝试从文件加载一组动态选项。我在构造函数中执行此文件读取操作,但似乎 Thor 类的 option 关键字在 initialize 方法之前得到处理。

有什么想法可以解决这个问题吗?如果有人可以解释 option 关键字的工作原理,那也很棒吗?我的意思是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 )

【问题讨论】:

    标签: ruby dsl thor


    【解决方案1】:

    经过一些调整,我想我找到了一个看起来还不错的解决方案。但不确定将代码放在这样的模块中是一个好习惯。但无论如何:

    #!/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 )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-06
      • 1970-01-01
      • 2011-05-09
      相关资源
      最近更新 更多