Ruby试图以编程方式避免子类中的多个定义

时间:2014-02-20 23:33:31

标签: ruby metaclass

安静的红宝石我无法弄清楚什么。 这是一个示例代码

class Big
  def self.metaclass; class << self; self; end; end

  def self.convertor b
    metaclass.instance_eval do
      define_method( :convert ) do |val|
        return b val
       end
    end
  end
end

class Small < Big
  convertor { |v| v.to_i + 1 }
end

puts Small.convert('18')

目标是为Big提供很多子类,我希望避免在每个

中定义
def convert(val)
  return conversion_specific_to_subclass(val)
end

按照前一种方式,每个子类只有一行。但无法让它发挥作用。 我做错了什么?有没有更好的方法来实现我的愿望?

提前致谢

编辑:这里提到的是这段代码产生的错误(使用ruby 2.1.0)

test2.rb:4:in `convertor': wrong number of arguments (0 for 1) (ArgumentError)
from test2.rb:14:in `<class:Small>'`

2 个答案:

答案 0 :(得分:3)

你过度复杂了 - 因为你想要的只是将块绑定到特定方法名称的能力,就这样做!

class Big
  def self.converter(&block)
    define_singleton_method :convert, &block
  end
end

class Small < Big
  converter {|v| v.to_i + 1 }
end

这样,当您调用Small::converter时,它将定义一个类方法,该方法接受块args中定义的参数列表,返回值将是块的返回值。

答案 1 :(得分:0)

试试这段代码:

class Big
  def self.metaclass; class << self; self; end; end

  def self.convertor(&b)
    metaclass.instance_eval do
      define_method( :convert ) do |val|
        return b[val]
       end
    end
  end
end

class Small < Big
  convertor { |v| v.to_i + 1 }
end

puts Small.convert('18')

您的代码中存在两个问题。一,您必须使用&参数捕获块。所以,这是新的方法声明:

def self.convertor(&b)

最后,您必须在返回时使用块调用语法调用块,如下所示:

return b[val]

或者这个:

return b.call(val)

您无法调用b val之类的块。

此外,Ruby中的好风格始终包括括号。