From: Eric Mahurin Date: 2008-06-06T21:17:23+09:00 Subject: Re: A crosspost from the Perl Community On Fri, Jun 6, 2008 at 6:31 AM, Dave Bass wrote: > Eric Mahurin wrote: >> No, ruby is still call-by-value. The "value" is an object reference >> (or simply an object in ruby terms). > > So you pass a reference to a function. Isn't this call-by-reference??? The traditional "reference" in "call-by-reference" is an lvalue reference. > Whatever the technicalities, what I mean is this. In Perl: > > sub upper > { > my $x = shift; > $x =~ tr/a-z/A-Z/; > } > > $a = "hello"; > upper($a); > print $a; # => "hello" > > $a is unchanged because $x is a local copy of $a; changing $x leaves $a > unchanged. perl actually is call-by-reference. $x is a local copy, but $_[0] is an lvalue reference to $a. Try this: sub upper { $_[0]=~ tr/a-z/A-Z/; } $a = "hello"; upper($a); print $a; # => "HELLO" sub swap {@_[0..1] = ($_[1], $_[0])} $a = 1; $b = 2; swap($a, $b); print("$a $b\n"); # => "2 1" But in Ruby: > > def upper(x) > x.upcase! > end > > a = "hello" > upper(a) > print a # => "HELLO" > > The original a is changed because upper has direct access to it. upper didn't change the variable "a" (the lvalue). It still has the same object it had before it called upper. upper did change the object that "a" had though. Compare to: def swap(a, b) a,b = b,a end a = 1 b = 2 swap(a, b) print("#{a} #{b}\n") # => "1 2" > You can > get the same effect in Perl using explicit referencing and > dereferencing: > > sub upper > { > my $x = shift; > $$x =~ tr/a-z/A-Z/; > } > > $a = "hello"; > upper(\$a); > print $a; # => "HELLO" Yep. Ruby's objects are equivalent to Perl's references. When you say this is ruby: a = "hello" it is equivalent to this in Perl: $a = \"hello" In ruby, I sometimes miss the ability to easily reference and dereference lvalues. There is always another way, but having lvalue references/pointers would sometimes be more elegant.