2016-03-07 53 views
0

我試圖從Ruby Commander Gem'借用'一些代碼。在自述的例子中,他們表現出了一些方法調用你在你的程序將是這樣的:獲取方法別名

require 'commander/import' 
program :name, 'Foo Bar' 

的方法程序是指揮官模塊,亞軍類英寸如果按照需要的鏈接,你會得出以下模塊:

module Commander 
module Delegates 
%w(
    add_command 
    command 
    program 
    run! 
    global_option 
    alias_command 
    default_command 
    always_trace! 
    never_trace! 
).each do |meth| 
    eval <<-END, binding, __FILE__, __LINE__ 
    def #{meth}(*args, &block) 
     ::Commander::Runner.instance.#{meth}(*args, &block) 
    end 
    END 
end 

    def defined_commands(*args, &block) 
    ::Commander::Runner.instance.commands(*args, &block) 
    end 
end 
end 

在指揮官模塊,亞軍類,這是相關代碼:

def self.instance 
    @singleton ||= new 
end 

def program(key, *args, &block) 
    if key == :help && !args.empty? 
    @program[:help] ||= {} 
    @program[:help][args.first] = args.at(1) 
    elsif key == :help_formatter && !args.empty? 
    @program[key] = (@help_formatter_aliases[args.first] || args.first) 
    elsif block 
    @program[key] = block 
    else 
    unless args.empty? 
     @program[key] = (args.count == 1 && args[0]) || args 
    end 
    @program[key] 
    end 
end 

我抄這個代碼到我自己程序,它似乎不工作,因爲我得到一個方法未發現程序錯誤。如果我將Runner實例化爲runner並調用runner.program,它就可以正常工作。

在我的版本,這是所有在一個文件中,我有

module Repel 
    class Runner 
    # the same methods as above 
    end 

    module Delegates 
    def program(*args, &block) 
     ::Repel::Runner.instance.program(*args, &block) 
    end 
    end 
end 
module Anthematic 
    include Repel 
    include Repel::Delegates 

    #runner = Runner.new 
    #runner.program :name, 'Anthematic' 

    program :name, 'Anthematic' 
    ... 
end 

我得到的錯誤是:

:未定義的方法`方案」爲Anthematic:模塊(NoMethodError)

註釋掉的代碼在未註釋時有效。

如何讓代碼工作,或者,有沒有更好的方法來做到這一點?我不知道eval聲明的其餘部分發生了什麼。我知道參數的數量在程序def中是關閉的。我有與他們對齊的另一種方法相同的問題。

回答

1

而不是

include Repel::Delegates 

includes模塊方法爲實例方法,你應該

extend Repel::Delegates 

extend類的方法。

+0

這樣做。任何他們想要做什麼的想法:eval << - END,binding,__FILE__,__LINE__ def#{meth}(* args,&block) :: Commander :: Runner.instance。#{meth}( * args,&block) end END – curt

+0

他們委託這些方法。 ''binding,FILE,LINE'只是爲了幫助調試器/文檔生成器來解決這些創建的即時方法。 ['source_location'](http://ruby-doc.org/core-2.1.5/UnboundMethod.html#method-i-source_location)等 – mudasobwa