继承的动态元编程方法
Dynamic metaprogrammed methods on inheritance
请原谅我的例子;我正在尝试开发一个独立的例子来表达我的要求,它可能看起来太做作了:
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"
最后一行应该是 return "piggie walk"
,但事实并非如此。为什么会发生这种情况以及如何使其使用 Pig
?
中定义的常量
您还需要在子class 中添加define_method。因为在 pig class 中搜索 walk 方法时发生了什么,找不到它并检查了 super class。现在 super class 有自己的常量 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
如果您不想要 bark 方法,只需重写 walk 方法即可。
尝试这样的事情
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
请原谅我的例子;我正在尝试开发一个独立的例子来表达我的要求,它可能看起来太做作了:
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"
最后一行应该是 return "piggie walk"
,但事实并非如此。为什么会发生这种情况以及如何使其使用 Pig
?
您还需要在子class 中添加define_method。因为在 pig class 中搜索 walk 方法时发生了什么,找不到它并检查了 super class。现在 super class 有自己的常量 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
如果您不想要 bark 方法,只需重写 walk 方法即可。
尝试这样的事情
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