2016-03-07 10 views
0

Я пытаюсь «заимствовать» некоторый код из Ruby Commander Gem. В примере в файле Readme, они показывают количество вызовов методов, которые вы размещаете в вашей программе, как это:Получение псевдонима для работы

программа
require 'commander/import' 
program :name, 'Foo Bar' 

Метод находится в модуле Commander, Runner класса. Если следовать требуют ссылок, которые вы придете к следующему модулю:

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 

В модуле Commander, класс Runner, это уместный код:

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.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

Смежные вопросы