继承的动态元编程方法

时间:2015-07-16 11:48:01

标签: ruby metaprogramming

对不起我的例子;我正在尝试开发一个独立的例子来表达我的要求,它可能看起来太做作了:

class Animal
  NAME = 'no name'

  %w(bark walk).each do |action|
    define_method(action) do
      NAME + ' ' + action
    end
  end
end

class Pig < Animal
  NAME = 'piggie'
end

Animal.new.walk # => "no name walk"
Pig.new.walk # => "no name walk"

最后一行预计会返回"piggie walk",但它不会。为什么会发生这种情况以及如何使用Pig中定义的常量?

2 个答案:

答案 0 :(得分:1)

尝试这样的事情

class Animal
  def initialize
    @name ||= "no name"
  end 

  %w(bark walk).each do |action|
    define_method(action) do
      "#{@name} #{action}"
    end 
  end 
end

class Pig < Animal
  def initialize
    @name = 'piggie'
  end 
end

Animal.new.walk # => "no name walk"
Pig.new.walk

答案 1 :(得分:0)

您还需要在子类中添加define_method。因为在猪班中发生了seach walk方法,找不到它并检查了超级类。现在超类有自己的常量NAME,它会使用它。试试这个

class Animal
  NAME = 'no name'
 %w(bark walk).each do |action|
    define_method(action) do
      NAME + ' ' + action
    end
  end
end

class Pig < Animal
  NAME = 'piggie'
 %w(bark walk).each do |action|
    define_method(action) do
      NAME + ' ' + action
    end
  end
end

Animal.new.walk
Pig.new.walk

如果你不想要树皮方法,只需覆盖步行方法而不是两者。