获取方法别名

时间:2016-03-07 19:04:41

标签: ruby delegation

我正在尝试'借用'Ruby Commander Gem中的一些代码。在自述文件的示例中,它们显示了您在程序中放置的许多方法调用,如下所示:

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并调用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的未定义方法`program':Module(NoMethodError)

注释掉的代码在取消注释时有效。

如何让代码工作,或者,有更好的方法吗?我不知道在eval语句的其余部分发生了什么。我知道程序def中的参数数量是关闭的。我对它们对齐的另一种方法有同样的问题。

1 个答案:

答案 0 :(得分:1)

而不是

include Repel::Delegates

哪个includes模块方法作为实例方法,你应该

extend Repel::Delegates

extend类方法。