Reputation: 5204
In C programming I believe they call this pass by reference. What I want to do is this.
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'
After b.change_foo
I would like the value of a.foo
to be modified. Is there a way of passing the reference of @foo
from class A
to module B
instead of the value?
Upvotes: 1
Views: 1765
Reputation: 1082
Objects are passed as reference in Ruby, but not pointers to variables. This means that, although you can modify any object, if you change the variable's reference, this change will occur only in the current scope. I'd recommend you to actually change your architecture and use more object-oriented techniques, instead of trying to rely on error-prone language features like this. For example, you can use composition and delegation to implement what you're trying to accomplish:
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
I don't know exactly your purpose, but I'd probably not dynamically extend modules in a factory method like this. I prefer to create classes whose purpose is clear, without depending on context.
Upvotes: 1
Reputation: 230481
With this concrete example of strings, you can make it work.
module B
attr_accessor :foo
def change_foo
# @foo = 'bar' # this won't work
foo.replace('bar')
end
end
When you do a @foo = 'bar'
, you're completely breaking any connection between foo
of B and foo
of A. They're now two separate objects.
What the code above does is, instead of making another object, use the reference to the object to call a method on it (which will change its state). Will work equally well with other mutable objects (arrays, hashes, instances of your custom classes). But not with immutable primitives like integers.
Is there a way of passing the reference of @foo from class A to module B instead of the value?
A reference (or a "pointer", in C-speak) is actually passed here. You then overwrite it.
Upvotes: 4