Who modified my local variable?
Jacob Fugal
lukfugl at gmail.com
Tue Jun 13 10:31:19 MDT 2006
On 6/13/06, Shane Hathaway <shane at hathawaymix.org> wrote:
> So again, I think a better way to express your point is to say that Java
> passes primitives by value and objects by reference. Higher level
> languages like Python do away with primitives and pass everything by
> reference.
While I can't speak -- not knowing -- to whether Java passes objects
by reference or references by value, there *is* an important
difference. For instance in Ruby, it is quite clear that references
are passed by value. The objects are *not* passed by reference.
Passing by reference and passing references by value are illustrated
by this C++ code:
void myFunc1(int c) {
c = 5;
printf("in myFunc1, c = %d\n", c);
}
void myFunc2(int &c) {
c = 5;
printf("in myFunc2, c = %d\n", c);
}
int main(void) {
int x = 2;
printf("before myFunc1, x = %d\n", x);
myFunc1(x);
printf("after myFunc1, x = %d\n", x);
myFunc2(x);
printf("after myFunc2, x = %d\n", x);
return 0;
}
Output:
before myFunc1, x = 2
in myFunc1, c = 5
after myFunc1, x = 2
in myFunc2, c = 5
after myFunc2, x = 5
In the call to myFunc1, c is a new variable which holds a copy of the
data that was in x. Standard pass by value. Once the call returns, x
is unchanged. In the call to myFunc2, c is a variable that refers to
the same memory location as x, so when c is assigned to, x is assigned
to as well.
But in Ruby, objects are not passed by reference, but instead all
variables *are* references, which are then passed by value. Example:
(using a string instead of an int to afford mutability; Fixnums are
immutable in Ruby):
def my_func1(c)
c = c.capitalize
puts "in my_func1, c = '#{c}'"
end
def my_func2(c)
c.capitalize!
puts "in my_func2, c = '#{c}'"
end
x = "hello, world."
puts "before my_func1, x = '#{x}'"
my_func1(x)
puts "after my_func1, x = '#{x}'"
my_func2(x)
puts "after my_func2, x = '#{x}'"
Output:
before my_func1, x = 'hello, world.'
in my_func1, c = 'Hello, world.'
after my_func1, x = 'hello, world.'
in my_func2, c = 'Hello, world.'
after my_func2, x = 'Hello, world.'
So you can see from the first call that the variable is *not* passed
by reference; assigning to c has no effect on x, as it did in the C++
example. But my_func2 demonstrates that we're not passing the string
by value (copying) either, since the same object is referred to by
both c and x; mutating c with the in-place #capitalize! message
affected x as well. This is because both c and x did refer to the same
object. What c and x contain are not the object itself, but references
(pointers, basically) to the object. That reference is passed by
value, so assignment in my_func1 only overwrites the copied reference
and not the referred to object, yet my_func2 can operate on that
reference and be working with the same object.
Jacob Fugal
More information about the PLUG
mailing list