2016-03-07 55 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