Reputation: 15205
I'm a bit of Ruby, noob, and there's some basic thing I'm not getting. I have something like this:
def my_method
attr1 = 'new 1 value'
attr2 = 'new 2 value'
puts "#{attr1} - #{attr2}"
puts "Should be same? #{to_s}"
end
def to_s
"#{attr1} - #{attr2}"
end
When I call my_method I get:
new 1 value - new 2 value
Should be same? old 1 value - old 2 value
Huh?
Upvotes: 1
Views: 90
Reputation:
This is because in Ruby
x = y
is always an assignment of the value resulting from y
to the variable x
while
obj.x = y
is always sending the x=
message to the object obj
(with the value resulting from y
).
In Ruby attributes/properties are really just methods! Thus, try:
self.attr1 = 'new 1 value'
self.attr2 = 'new 2 value'
On the other hand, y
may or may not be a method call (read: property fetch). It depends on if there is already a variable y
in scope or not because variables shadow methods. This is why attr1
and attr2
work in to_s
without needing to be prefixed.
Happy coding.
Upvotes: 1
Reputation: 4383
It's the scope attr1
and attr2
are local variables.
So when you're calling to_s
it looking for attr_1
and attr_2
that you've declared (probably) in the class scope. Those won't get overwritten when you run my_method
instead you just created a new variable in a smaller scope.
Try using @attr_1
and @attr_2
instead.
Check out Local Variable Gotchas
Upvotes: 1
Reputation: 37517
There are two ways to do it. One is to use class-scoped variables instead of local variables:
class MyClass
def my_method
@attr1 = 'new 1 value'
@attr2 = 'new 2 value'
puts "#{@attr1} - #{@attr2}"
puts "Should be same? #{self.to_s}"
end
def to_s
"#{@attr1} - #{@attr2}"
end
end
m = MyClass.new
m.my_method
Output:
new 1 value - new 2 value
Should be same? new 1 value - new 2 value
The other way is to use attributes, which you have to specifically call as methods on self
:
class MyClass
attr_accessor :attr1,:attr2
def my_method
self.attr1 = 'new 1 value'
self.attr2 = 'new 2 value'
puts "#{attr1} - #{attr2}"
puts "Should be same? #{self.to_s}"
end
def to_s
"#{attr1} - #{attr2}"
end
end
m = MyClass.new
m.my_method
This has the same output.
Upvotes: 1