As long as you've been hanging out here, I'm surprised if you are
really surprised by this.
In order to get completely comfortable with Ruby you need to
understand the relationships and differences between objects and
variables
Objects are instances of classes, and typically have state, in some
cases like Fixnums the only state is really the object's identity, and
such objects are immutable, if two such objects have different state,
then they MUST be different objects. There is only one 1 object and
one 5 object. Symbols are similar in that there is only one instance
of symbol with a particular value.
Some clases have methods which change the state of an object without
changing it's identity. String.gsub! is one such method. You can
write such mutating methods yourself, clearly for your own classes,
but also for core classes which already have mutating methods by
writing new methods interms of the existing mutating methods.
A variable is not an object, rather it is a temporary binding to a
particular object which is established by, and can be changed by an
assignment expression, syntactic sugar which disguises an assignment
expression (e.g. x += y). Variables include locals, method
parameters, instance variables, element slots in arrays, and block
arguments (which are distinguished from local variables in Ruby 1.9).
So variables can't be mutated, they can only have their binding
switched to another variable, if two variables reference the same
object, and the binding of one of those variables changes to reference
another object, the other variable is unaffected.
def test(x)
x = 10
end
num = 5
test num
puts num
--output:--
5
But, again since variables are bindings to objects, if two variables
reference the same object, and that object is mutated, then the change
in state will by visible through ANY reference to that particular
object.
x and num are two different variables. At the time test is called,
num is bound to 5, inside the context of the invocation of test, x
starts out bound to 5, then the assignment changes the binding of x
to 1, and leaves the binding of num alone. Imagine the code had been:
num=5
x = 1
puts num
output:
5
I hope that this is completely unsurprising, I suspect the surprise
might come from the assumption that somehow x and num are the same
variable because of the formal/actual parameter pairing.
In the case of method arguments (and block arguments in Ruby 1.9) the
name is local to the method (or block). This means that x and num are
indeed not the same variable, but two variables one of which (x) is
initialized by the call to refer to the same object resulting from the
expression used in the call, which in this cases happen to simply be
the variable num.
Imagine that we'd called
test(num + 1)
Here the actual value would be not 5 but 6, and there's no visible
variable which corresponds to the actual expression.
And even if the FORMAL parameter name were changed:
def test(num)
num = 10
end
num = 5
test num
puts num
--output:--
5
The result would be the same, since the names num at the top level,
and num inside the test method are two different variables.
HTH
And of course there's my oldie but goodie:
http://talklikeaduck.denhaven2.com/2006/09/13/on-variables-values-and-objects
···
On Sat, Oct 31, 2009 at 5:03 AM, 7stud -- <bbxx789_05ss@yahoo.com> wrote:
Judson Lester wrote:
Finally: ruby is a pass-by-reference language, so if you actually do
make
changes the parameters of a method, the callers variables will change as
well.
def test(x)
x = 10
end
num = 5
test num
puts num
--output:--
5
???
--
Rick DeNatale
Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale