我对Ruby很陌生,似乎我仍然混淆mixin并在课堂中包含模块。我希望能够访问类中模块中定义的实例变量(@)。 我有以下代码:
module ModuleB
attr_reader :b
def ModuleB.initialize(browser)
puts "initialize from ModuleB"
@browser = browser
@b = 5
end
end
module ModuleA
attr_reader :a
include ModuleB
def ModuleA.initialize(browser)
ModuleB.initialize(browser)
puts "initialize from ModuleA"
@browser = browser
@a = @b
end
def action_1
@a = @b + 1
return @a
end
end
class ClassA
include ModuleA
def initialize(browser)
ModuleA.initialize(browser)
@browser = browser
puts 'initialize - method in ClassA'
@c = @a
@d = @b
puts "a = #{@a}"
puts "b = #{@b}"
puts "c = #{@c}"
puts "d = #{@d}"
end
end
s = 'hello'
instA = ClassA.new(s)
puts instA.action_1
以下是我得到的输出:
initialize from ModuleB
initialize from ModuleA
initialize - method in ClassA
a =
b =
c =
d =
mixin_example2.rb:23:in `action_1': undefined method `+' for nil:NilClass (NoMethodError)
from mixin_example2.rb:46:in `<main>'
似乎@a
和@b
未初始化。
另外一点是,我不能使用&#39; +&#39; action_1
方法中的运算符。
我错过了什么?
很抱歉,如果我重复了可能已经提出的问题,但到目前为止我还没有找到答案。
答案 0 :(得分:2)
实例变量属于实例(这就是为什么它们被称为&#34;实例变量&#34;)。这里有三个感兴趣的对象,每个对象都有自己的@b
,它与其他对象的任何其他@b
无关:ModuleA
有自己的对象@b
和ModuleB
一样,instA
也有自己的@b
。
这是您正在尝试做的更明智的实现:
module ModuleB
def initialize(browser)
puts "initialize from ModuleB"
@browser = browser
@b = 5
end
end
module ModuleA
include ModuleB
def initialize(browser)
super
puts "initialize from ModuleA"
@a = @b
end
def action_1
@a = @b + 1
end
end
class ClassA
include ModuleA
def initialize(browser)
super
puts 'initialize - method in ClassA'
@c = @a
@d = @b
puts "a = #@a"
puts "b = #@b"
puts "c = #@c"
puts "d = #@d"
end
end
s = 'hello'
instA = ClassA.new(s)
# initialize from ModuleB
# initialize from ModuleA
# initialize - method in ClassA
# a = 5
# b = 5
# c = 5
# d = 5
#=> #<ClassA:0x007f8b5f12e110 @a=5, @b=5, @browser="hello", @c=5, @d=5>
puts instA.action_1
# 6