Ruby mixin - 在 class 个实例中访问模块实例变量
Ruby mixin - accessing module instance variables in class instances
我是 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
未初始化。
另外,我不能在 action_1
方法中使用“+”运算符。
我错过了什么?
抱歉,如果我重复了可能已经提出的问题,但到目前为止我还没有找到答案。
实例变量属于实例(这就是它们被称为"instance variables"的原因)。您在这里有三个感兴趣的对象,每个对象都有自己的 @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
我是 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
未初始化。
另外,我不能在 action_1
方法中使用“+”运算符。
我错过了什么?
抱歉,如果我重复了可能已经提出的问题,但到目前为止我还没有找到答案。
实例变量属于实例(这就是它们被称为"instance variables"的原因)。您在这里有三个感兴趣的对象,每个对象都有自己的 @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