在C编程中,我相信他们称之为传递。我想做的就是这个。
class A
attr_accessor :foo
def initialize
@foo = 'foo'
end
def get_b
_b = Object.new
_b.extend B
_b.foo = @foo
end
module B
attr_accessor :foo
def change_foo
@foo = 'bar'
end
end
end
a = A.new
puts a.foo # 'foo'
b = a.get_b
puts b.foo # 'foo'
b.change_foo
puts b.foo # 'bar'
puts a.foo # This should also be 'bar' but is instead still 'foo'
在b.change_foo
之后,我希望修改a.foo
的值。有没有办法将@foo
的引用从class A
传递给module B
而不是值?
答案 0 :(得分:3)
通过这个字符串的具体示例,您可以使其工作。
module B
attr_accessor :foo
def change_foo
# @foo = 'bar' # this won't work
foo.replace('bar')
end
end
当你执行@foo = 'bar'
时,你完全打破了B的foo
和A的foo
之间的任何联系。它们现在是两个独立的对象。
上面的代码所做的是,而不是创建另一个对象,使用对象的引用来调用它的方法(这将改变它的状态)。与其他可变对象(数组,哈希,自定义类的实例)一样可以正常工作。但不是像整数这样的不可变原语。
有没有办法将@foo的引用从A类传递给模块B而不是值?
参考(或“指针”,在C语言中) 实际上是在这里传递的。然后你覆盖它。
答案 1 :(得分:1)
对象在Ruby中作为引用传递,但不是指向变量的指针。这意味着,虽然您可以修改任何对象,但如果更改变量的引用,则此更改将仅在当前范围内发生。我建议您实际更改架构并使用更多面向对象的技术,而不是试图依赖像这样的容易出错的语言功能。例如,您可以使用合成和委派来实现您尝试完成的任务:
class A
attr_accessor :foo
def initialize
@foo = 'foo'
end
def get_b
_b = Object.new
_b.extend B
_b.a = self
end
module B
attr_accessor :a
def foo
a.foo
end
def foo=(value)
a.foo = value
end
def change_foo
a.foo = 'bar'
end
end
end
我不确切地知道你的目的,但我可能不会像这样在工厂方法中动态扩展模块。我更喜欢创建目的明确的类,而不依赖于上下文。