我想调用我在一个类中包含的两个模块的构造函数,但我不知道该怎么做。
module GameObject
attr_reader :x, :y
def initialize(x, y)
@x, @y = x, y
end
end
module Attackable
attr_reader :health, :damage
def initialize(health, damage)
@health, @damage = health, damage
end
end
class SuperMario
include GameObject
include Attackable
def initialize(x, y, health, damage)
.. how to call the above constructors?
end
end
如何调用Attackable和GameObject的构造函数?
答案 0 :(得分:1)
您可以在类初始化程序中显式调用module
的方法,如下所示:
def initialize(x, y, health, damage)
m = GameObject.instance_method( :initialize )
m.bind(self).call( x, y )
m = Attackable.instance_method( :initialize )
m.bind(self).call( health, damage)
end
答案 1 :(得分:0)
我想你来自C ++世界,允许多重继承...简而言之,Ruby只提供单一继承,并且不允许挑选你正在调用的父方法。温和地说,这就是你想要实现的目标。模块不会为您提供任何良好的解决方法 - 即使在考虑prepend
或self.included
以及元编程工具箱的其余部分之后 - 除了在没有名称冲突的特定情况下
你可以做的是重命名initialize方法,使其逻辑在特定于其模块的函数中,并调用 。除此之外:在模块中定义initialize
方法通常会产生代码气味。
答案 2 :(得分:0)
我今天学到了新东西:
module B
def cat(a) puts "in B, a = #{a}" end
end
module C
def cat(a) puts "in C, a = #{a}"; super a+1; end
end
class A
include B
include C
def cat(a) puts "in A, a = #{a}"; super a+1; end
end
A.new.cat(2)
# => in A, a = 2
# => in C, a = 3
# => in B, a = 4
您的问题不仅限于initialize
,这就是我用通用方法说明此行为的原因。我原以为includes
会混合使用其他两个cat
方法,因此结果与:
class D
def cat(a) puts "in 1st, a = #{a}" end
def cat(a) puts "in 2nd, a = #{a}"; super a+1; end
def cat(a) puts "in 3rd, a = #{a}"; super a+1; end
end
D.new.cat(2)
# => in 3rd, a = 2
# => module.rb:24:in `cat': super: no superclass method `cat' for
# #<D:0x007faadb99acb8> (NoMethodError) from module.rb:27:in `<main>'
我对@ sawa关于“超级”的评论感到困惑,发现我错了。 (我希望不是所有读这篇文章的人都会思考,“那么还有什么新东西?”。)