Forum: Ruby pass by reference?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Andy K. (Guest)
on 2007-01-27 01:28
(Received via mailing list)
Hello,

Is there a way to pass variables by reference into function.

I have large string to pass and the pass by value seems to be eating up
too much memory.

Thanks,

Andy
Vincent F. (Guest)
on 2007-01-27 01:33
(Received via mailing list)
Andy K. wrote:
> Hello,
>
> Is there a way to pass variables by reference into function.
>
> I have large string to pass and the pass by value seems to be eating up
> too much memory.

  You don't actually need to do anything: everything in ruby is passed
by reference, (excepted integers, symbols, nil, false and true - am I
missing one ?)

  Cheers,

  Vincent
Per V. (Guest)
on 2007-01-27 01:35
Everything is pass-by-reference in Ruby. There is no pass-by-value. So
your memory problems must have another cause.

Andy K. wrote:
> Hello,
>
> Is there a way to pass variables by reference into function.
>
> I have large string to pass and the pass by value seems to be eating up
> too much memory.
>
> Thanks,
>
> Andy
Wolfgang N. (Guest)
on 2007-01-27 01:55
(Received via mailing list)
Per V. schrieb:
> Everything is pass-by-reference in Ruby. There is no pass-by-value. So
> your memory problems must have another cause.

May be, that you do in fact a copy by some other operations, that create
a new
String object and copy the original. E.g.

s = t + ''

creates a new string with the same contents. There are several
possibilities to
do things like that without recognizing it.

Wolfgang Nádasi-Donner
unknown (Guest)
on 2007-01-27 02:16
(Received via mailing list)
Hi --

On Sat, 27 Jan 2007, Per V. wrote:

> Andy K. wrote:
>> Hello,
>>
>> Is there a way to pass variables by reference into function.
>>
>> I have large string to pass and the pass by value seems to be eating up
>> too much memory.
>>
> Everything is pass-by-reference in Ruby. There is no pass-by-value. So
> your memory problems must have another cause.

I've always looked at it as: pass by value, where the "values" are
(mostly) references.  For example:

   a = "abcde"         # a now contains a reference to that string
   do_something(a)     # pass the reference contained in a


David
Gavin K. (Guest)
on 2007-01-27 02:20
(Received via mailing list)
On Jan 26, 4:32 pm, Vincent F. <removed_email_address@domain.invalid>
wrote:
> You don't actually need to do anything: everything in ruby is passed
> by reference, (excepted integers, symbols, nil, false and true - am I
> missing one ?)

How do you know if those are passed by reference or by value? It's a
very existential question:
If you pass an immutable type by reference, does it make a sound?
Er, I mean...
If you passed an immutable type by reference, how would you know that
it wasn't passed by value?

I leave you with this:

irb(main):001:0> values = [ 1, :foo, true, false, nil ]
=> [1, :foo, true, false, nil]

irb(main):002:0> puts values.map{ |v| v.object_id }
3
231138
2
0
4
=> nil

irb(main):003:0> def foo( *args ); puts args.map{ |v| v.object_id };
end
=> nil

irb(main):004:0> foo( *values )
3
231138
2
0
4
=> nil

irb(main):005:0> b = :foo
=> :foo

irb(main):006:0> b.object_id
=> 231138

It's almost the reverse of what you said - it's not that immediate
values are passed by value, but rather that every reference to an
immediate value refers to the same object.
Martin C. Martin (Guest)
on 2007-01-27 02:25
(Received via mailing list)
Phrogz wrote:
> If you pass an immutable type by reference, does it make a sound?
> Er, I mean...
> If you passed an immutable type by reference, how would you know that
> it wasn't passed by value?

Is there any way for the function you're calling to modify the value of
the variable in the caller?  Pass by reference can do that.

- Martin
unknown (Guest)
on 2007-01-27 02:44
(Received via mailing list)
Hi --

On Sat, 27 Jan 2007, Martin C. Martin wrote:

>
>
> Phrogz wrote:
>> If you pass an immutable type by reference, does it make a sound?
>> Er, I mean...
>> If you passed an immutable type by reference, how would you know that
>> it wasn't passed by value?
>
> Is there any way for the function you're calling to modify the value of the
> variable in the caller?  Pass by reference can do that.

You can modify the object to which the variable refers:

   def change_me(obj)
     obj << "hi"
   end

   arr = [1,2,3]
   change_me(arr)
   p arr          # [1, 2, 3, "hi"]

In this example, arr contains a reference to an array.  In change_me,
obj contains another copy of the same reference, so you can use it to
manipulate and change the original array.

I still wouldn't call this pass by reference (see my earlier post in
this thread).


David
Robert K. (Guest)
on 2007-01-27 09:51
(Received via mailing list)
On 27.01.2007 01:43, removed_email_address@domain.invalid wrote:
>> Is there any way for the function you're calling to modify the value
>   p arr          # [1, 2, 3, "hi"]
>
> In this example, arr contains a reference to an array.  In change_me,
> obj contains another copy of the same reference, so you can use it to
> manipulate and change the original array.
>
> I still wouldn't call this pass by reference (see my earlier post in
> this thread).

Absolutely right: Ruby uses pass by value - with references.

irb(main):004:0> def foo(x) x = 10 end
=> nil
irb(main):005:0> def bar; x = 20; foo(x); x end
=> nil
irb(main):006:0> bar
=> 20
irb(main):007:0>

There is no standard way (i.e. other than involving eval and
metaprogramming magic) to make a variable in a calling scope point to
another object.  And, btw, this is independent of the object that the
variable refers to.  Immediate objects in Ruby seamlessly integrate with
the rest (different like POD's in Java for example) and from a Ruby
language perspective you don't see any difference (other than
performance maybe).  This is one of the reasons why Ruby is so elegant.

Kind regards

  robert
Robert D. (Guest)
on 2007-01-27 09:52
(Received via mailing list)
On 1/27/07, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:
> >> If you passed an immutable type by reference, how would you know that
>    end
> this thread).
Just to demonstrate your point

def modifying a_param
    a_param = "hi"
end

a_value = "low"

modifying a_value
case a_value
when "hi"
    puts "Passed by reference"
when "low"
   puts "Passed by value"
else
   puts "Passed away"
end

or to put it different
x = a.object_id
method a
a.object_id == x  # for sure

Robert

David
unknown (Guest)
on 2007-01-27 13:05
(Received via mailing list)
Hi --

On Sat, 27 Jan 2007, Robert D. wrote:

>> >> Er, I mean...
>>      obj << "hi"
>> I still wouldn't call this pass by reference (see my earlier post in
>
> modifying a_value
> case a_value
> when "hi"
>   puts "Passed by reference"
> when "low"
>  puts "Passed by value"
> else
>  puts "Passed away"
> end

That's a somewhat different point, though, having to do with variable
scope and (re)assignment semantics.  What you're doing here
essentially is:

   a = "low"
   b = a
   b = "hi"
   puts a     # low

That's going to happen whether a method call is involved or not.


David
unknown (Guest)
on 2007-01-27 13:11
(Received via mailing list)
Hi --

On Sat, 27 Jan 2007, Robert K. wrote:

>>>
>>   change_me(arr)
>
> irb(main):004:0> def foo(x) x = 10 end
> => nil
> irb(main):005:0> def bar; x = 20; foo(x); x end
> => nil
> irb(main):006:0> bar
> => 20
> irb(main):007:0>

I'm not sure that demonstrates the "values that are references" thing,
though.  You're reassigning to x in foo, which creates a new local x;
but I think that's just part of the assignment semantics.  Or are you
assuming that if pass by reference were involved, then assignment
would work differently?


David
Robert D. (Guest)
on 2007-01-27 13:13
(Received via mailing list)
On 1/27/07, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:
>    puts a     # low
>
> That's going to happen whether a method call is involved or not.


David, it is not my fault  that parameter  passing by value has the same
semantics as  reference assignment  ;) (it probably is what is happening
behind the scenes, a new reference is allocated and the formal parameter
is
copied to it).
Do you see what I wanted to show?

Cheers
Robert

David
Wolfgang N. (Guest)
on 2007-01-27 13:35
(Received via mailing list)
>>>>> Code >>>>>

def modifying(a_param)
   a_param = "hi"
end

def modifying2(a_param=a_value)
   a_param = "hi"
end

def modifying3(a_param)
   a_param[0..-1]= "hi"
end

a_value = "low"
modifying a_value
case a_value
when "hi"
   puts "Passed by reference"
when "low"
  puts "Passed by value"
else
  puts "Passed away"
end

a_value = "low"
modifying2 a_value
case a_value
when "hi"
   puts "Passed by reference"
when "low"
  puts "Passed by value"
else
  puts "Passed away"
end

a_value = "low"
modifying3 a_value
case a_value
when "hi"
   puts "Passed by reference"
when "low"
  puts "Passed by value"
else
  puts "Passed away"
end

 >>>>> Output >>>>>

Passed by value
Passed by value
Passed by reference

 >>>>> EoE >>>>>

I would name it somehow "call by assignment of value to local variable",
because
the value of the actual parameter is assigned to the local variable used
as a
formal parameter.

except for "Fixnum" etc. this is a pointer to an object. I one changes
the
object itself, it will work like  "by reference", otherwise only the
local
variable is affected, without having any effect to the outside world.

Wolfgang Nádasi-Donner
Wolfgang N. (Guest)
on 2007-01-27 13:40
(Received via mailing list)
>>>>> Code >>>>>

def modifying(a_param)
   a_param = "hi"
end

def modifying2(a_param=a_value)
   a_param = "hi"
end

def modifying3(a_param)
   a_param[0..-1]= "hi"
end

a_value = "low"
modifying a_value
case a_value
when "hi"
   puts "Passed by reference"
when "low"
  puts "Passed by value"
else
  puts "Passed away"
end

a_value = "low"
modifying2 a_value
case a_value
when "hi"
   puts "Passed by reference"
when "low"
  puts "Passed by value"
else
  puts "Passed away"
end

a_value = "low"
modifying3 a_value
case a_value
when "hi"
   puts "Passed by reference"
when "low"
  puts "Passed by value"
else
  puts "Passed away"
end

>>>>> Output >>>>>

Passed by value
Passed by value
Passed by reference

>>>>> EoE >>>>>

I would name it somehow "call by assignment of value to local variable",
because
the value of the actual parameter is assigned to the local variable used
as a
formal parameter.

except for "Fixnum" etc. this is a pointer to an object. If one changes
the
object itself, it will work like  "by reference", otherwise only the
local
variable is affected, without having any effect to the outside world.

Wolfgang Nádasi-Donner
unknown (Guest)
on 2007-01-27 13:47
(Received via mailing list)
Hi --

On Sat, 27 Jan 2007, Wolfgang Nádasi-Donner wrote:

> def modifying3(a_param)
> else
> else
> else
> puts "Passed away"
> end
>
>>>>>> Output >>>>>
>
> Passed by value
> Passed by value

But you've broken the bindings.  It's a whole new ballgame, as we say
here :-)

> Passed by reference

I would say: a reference, passed by value.

>>>>>> EoE >>>>>
>
> I would name it somehow "call by assignment of value to local variable",
> because the value of the actual parameter is assigned to the local variable
> used as a formal parameter.
>
> except for "Fixnum" etc. this is a pointer to an object. I one changes the
> object itself, it will work like  "by reference", otherwise only the local
> variable is affected, without having any effect to the outside world.

I consider the variable assignment semantics to be a separate matter.
For example:

   def x(a)
     a = "hello"
   end

Here, Ruby's rule is that the second a is a completely new binding,
and destroys the original binding.  I don't think that has anything to
do with whether the first a is a reference or a value.  In other
words, even if Ruby had pass by reference, I assume that a = "hello"
would still destroy the binding and create a new local variable.

(Of course, it's purely speculative, since it would be a completely
different language.)


David
Robert K. (Guest)
on 2007-01-27 14:00
(Received via mailing list)
On 27.01.2007 12:10, removed_email_address@domain.invalid wrote:
>>>>> If you pass an immutable type by reference, does it make a sound?
>>>     obj << "hi"
>>> I still wouldn't call this pass by reference (see my earlier post in
>> irb(main):007:0>
>
> I'm not sure that demonstrates the "values that are references" thing,
> though.  You're reassigning to x in foo, which creates a new local x;
> but I think that's just part of the assignment semantics.  Or are you
> assuming that if pass by reference were involved, then assignment
> would work differently?

I probably should have chosen different variable names.  I was trying to
make the point, that you cannot change a variable in bar by assigning in
foo.

Kind regards

  robert
Wolfgang N. (Guest)
on 2007-01-27 14:15
(Received via mailing list)
May be it will be clearer to name an assignment "a = someobject" by what
it
really means: "Give a reference to object 'someobject' a name 'a' by
definition". It's close to the ":=" used for definition in mathematics.

If one uses this "a" as a "reference to 'someobject'" as an actual
parameter in
a method call, it means, that the "reference to 'someobject'" is
actually used
in the method.

Clearly you cannot change "a", because you don't have access to this
name "a"
inside the method, but you can change the object "someobject" usually
without
any problems. If you change "someobject" this will have consequences for
'a',
because the object ist changed, the reference is still the same.

Wolfgang Nádasi-Donner
unknown (Guest)
on 2007-01-27 14:38
(Received via mailing list)
Hi --

On Sat, 27 Jan 2007, Wolfgang Nádasi-Donner wrote:

> any problems. If you change "someobject" this will have consequences for 'a',
> because the object ist changed, the reference is still the same.

Right -- I take that as the starting point -- but what I mean is that
the way the assignment/rebinding semantics work doesn't necessarily
pertain to the reference/value question.


David
Wolfgang N. (Guest)
on 2007-01-27 18:46
(Received via mailing list)
removed_email_address@domain.invalid schrieb:

> Right -- I take that as the starting point -- but what I mean is that
> the way the assignment/rebinding semantics work doesn't necessarily
> pertain to the reference/value question.

I agree. reference/value came from the world before talking about
objects. I
remember in Algol60 somehow the wording "after 'integer i;' the variable
'i IS
an integer".

We would never say that after writing "s = 'A Ruby String object'" the
variable
's' IS a String object - it gives a name for a special String object, or
references a special String object (see 1).

Wolfgang Nádasi-Donner

(1): This wording is is used from a German, who tries to find out the
best
English word for what in German will be called "benennt", or
"bezeichnet". I
don't know what wording is really good in English.
unknown (Guest)
on 2007-01-27 19:14
(Received via mailing list)
Hi--

On Sun, 28 Jan 2007, Wolfgang Nádasi-Donner wrote:

> We would never say that after writing "s = 'A Ruby String object'" the
> variable 's' IS a String object - it gives a name for a special String
> object, or references a special String object (see 1).

There's also the distinction between references and immediate
values... though as Robert K. said, most of the differences are
hidden from the programmer (like, there's no extra level of
indirection you have to explicitly do).

> Wolfgang Nádasi-Donner
>
> (1): This wording is is used from a German, who tries to find out the best
> English word for what in German will be called "benennt", or "bezeichnet". I
> don't know what wording is really good in English.

I think "betoken" is probably the closest etymologically to
"bezeichnen", but it's more archaic-sounding.  "Designate" might be a
good match.  (This is why we end up doing things like using
"reference" as a verb :-)


David
Thomas H. (Guest)
on 2007-01-27 20:26
(Received via mailing list)
"Phrogz" <removed_email_address@domain.invalid> wrote/schrieb
<removed_email_address@domain.invalid>:

> On Jan 26, 4:32 pm, Vincent F. <removed_email_address@domain.invalid>
> How do you know if those are passed by reference or by value?

def oi(obj)
  obj.object_id
end
x = "yeah" # or set it to anything else
oi(x) == x.object_id # => true

Regards
  Thomas
Austin Z. (Guest)
on 2007-01-27 20:30
(Received via mailing list)
On 1/26/07, Vincent F. <removed_email_address@domain.invalid> wrote:
> missing one ?)
Those are still passed by reference. It just so happens that they are
unique and immutable in the system, so it looks a lot like
pass-by-value.

-austin
Xavier N. (Guest)
on 2007-01-27 20:53
(Received via mailing list)
On Jan 27, 2007, at 7:29 PM, Austin Z. wrote:

>>   You don't actually need to do anything: everything in ruby is
>> passed
>> by reference, (excepted integers, symbols, nil, false and true - am I
>> missing one ?)
>
> Those are still passed by reference. It just so happens that they are
> unique and immutable in the system, so it looks a lot like
> pass-by-value.

I think the problem in these discussions is that "reference" in the
programming language jargon is not the same word as in "pass-by-
reference". This discussion is common in Java forums as well. Java is
pass-by-value.

In C++ since the copy constructor is involved, I found people in
freenode#c++ consider &-arguments to be pass-by-reference because
they can modify the objects in the caller, albeit the assigment test
discussed in the thread does not work, that'd be

   def m(b)
     b = 7
   end

   a = 3
   m(a)
   # a expected to be 7 in pass-by-reference

-- fxn
Robert D. (Guest)
on 2007-01-27 21:04
(Received via mailing list)
On 1/27/07, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:
> >
> There's also the distinction between references and immediate
> > don't know what wording is really good in English.
>
> I think "betoken" is probably the closest etymologically to
> "bezeichnen", but it's more archaic-sounding.  "Designate" might be a
> good match.  (This is why we end up doing things like using
> "reference" as a verb :-)


Designated is just fine, I do not know  the verb betoken.

However I do not necessarily agree with the post, still thinking...

Robert
Robert D. (Guest)
on 2007-01-27 21:13
(Received via mailing list)
On 1/27/07, Robert D. <removed_email_address@domain.invalid> wrote:
> > >
> > > We would never say that after writing "s = 'A Ruby String object'" the
> > > (1): This wording is is used from a German, who tries to find out the
>
> Designated is just fine, I do not know  the verb betoken.
>
> However I do not necessarily agree with the post, still thinking...
>
> Robert
>

Thinking period over ;)
In Ruby everything is passed by value, even Integers - or did I misread
the
sources?
In that case my apologies Austin.
This is consistent with behavior as well as with implementation.
Is there any reason to tweak the meaning of "passing by reference" and
"passing by value" just because we use "reference"  more often of how
vars
designate (ty Wolfgang) values (which happen to be objects).
"Passing by designation", if it makes things clearer, why not, but we
would
talk a language only Rubyists can understand!

Cheers
Robert





--
Robert D. (Guest)
on 2007-01-27 21:18
(Received via mailing list)
On 1/27/07, Robert D. <removed_email_address@domain.invalid> wrote:
> > >
> > > We would never say that after writing "s = 'A Ruby String object'" the
> > > (1): This wording is is used from a German, who tries to find out the
>
> Designated is just fine, I do not know  the verb betoken.
>
> However I do not necessarily agree with the post, still thinking...
>
> Robert
>

Thinking period over ;)
In Ruby everything is passed by value, even Integers - or did I misread
the
sources?
In that case my apologies Austin.
This is consistent with behavior as well as with implementation.
Is there any reason to tweak the meaning of "passing by reference" and
"passing by value" just because we use "reference"  more often of how
vars
designate (ty Wolfgang) values (which happen to be objects).
"Passing by designation", if it makes things clearer, why not, but we
would
talk a language only Rubyists can understand!

Cheers
Robert





--
Robert D. (Guest)
on 2007-01-27 21:21
(Received via mailing list)
SORRY folks my gmail went amok!!!
Thomas H. (Guest)
on 2007-01-27 21:25
(Received via mailing list)
Xavier N. <removed_email_address@domain.invalid> wrote/schrieb
<removed_email_address@domain.invalid>:

>    m(a)
>    # a expected to be 7 in pass-by-reference

That's another story. With the code above you rather reset b to a new
object instead of modifying the passed object. Look here:

def m(b)
  b.shift
  b.unshift(7)
end
a = [3]
m(a)
=> [7]

Would that be the same with pass-by-value? No, I don't think so.

Regards
  Thomas
Xavier N. (Guest)
on 2007-01-27 21:41
(Received via mailing list)
On Jan 27, 2007, at 8:25 PM, Thomas H. wrote:

>
> Would that be the same with pass-by-value? No, I don't think so.

Yes, that's the usual point in the discussion. Being able to change
the internal state of mutable objects is not a test for pass-by-
reference. Java is pass-by-value for instance (according to the JLS)
and that test passes.

Problem with the assignment-seen-in-the-caller test is what dblack
pointed out, it mixes assigment semantics.

In Perl, which is pass by reference, you can do this for example:

   $ perl -wle '$x = 0; sub { ++$_[0] }->($x); print $x'
   1

-- fxn
Austin Z. (Guest)
on 2007-01-27 21:51
(Received via mailing list)
The simplest way to remember this is that variables in Ruby aren't
chunks of memory. When C++ programmers say that they're passing
something by reference, they are simply doing a (slightly) safer
operation than passing a pointer around. They are *still* referencing
the memory block, but it's type checked.

In Ruby, inasmuch as variables contain anything, they contain a
reference. This applies even to immediate values such as nil, true,
false, integers, and symbols. It just so happens that, at least for
integers, the reference (the object ID, if you will) is the same as
the value, shifted left once -- at least in matzruby. The others are
all fixed object IDs.

Making a distinction between the passing semantics of immediate values
is a mistake; it invites people to peer too deeply under the hood of
Ruby. Better to clarify that integers are immediate  immutable values
and indicate that all variables are references and the references are
passed -- by value -- to methods.

Scope also enters into this, but that's been discussed clearly.

-austin
unknown (Guest)
on 2007-01-28 06:09
(Received via mailing list)
Hi --

On Sun, 28 Jan 2007, Thomas H. wrote:

>>
> end
> a = [3]
> m(a)
> => [7]
>
> Would that be the same with pass-by-value? No, I don't think so.

It depends what value you're passing.  If the value is an array, and
it gets copied into b, then it wouldn't work that way; but what's
happening is that a *reference* to an array is getting passed by
value.  That value (which is a reference to an array) is assigned to
the variable a in the caller's scope, and also to the variable b
inside the method.


David
Thomas H. (Guest)
on 2007-01-28 09:45
(Received via mailing list)
"Austin Z." <removed_email_address@domain.invalid> wrote/schrieb
<removed_email_address@domain.invalid>:

> The simplest way to remember this is that variables in Ruby aren't
> chunks of memory.

Or: they are a chunk of memory, but the only kind of value they can
contain is a reference to an object. A variable is not such an object,
i.e. there are no references to variables.

Ruby
~~~~

Var.  obj.-id  object
      +---+    +---+
a --->|   |    |   |
      |   |--->|   |
b --->|   |    |   |
      +---+    |   |
               |   |
               |   |
               |   |
               |   |
               +---+

If one passes a value, always an object id will be passed.

If one just uses variable ``a'', it will always go through the
automatial indirection of the object id. If ``a'' and ``b'' go through
the same indirection (using the same object id), then state can be
manipulated mutually.


C
~

Var.  memory
      +---+
a --->|   |
      |   |
b --->|   |
      |   |
      |   |
      |   |
      |   |
      |   |
      +---+

If one passes a value, the memory will be copied. Then state can no
longer be manipulated.

Regards
  Thomas
Tim X (Guest)
on 2007-01-28 10:10
(Received via mailing list)
removed_email_address@domain.invalid writes:

>>>>> If you pass an immutable type by reference, does it make a sound?
>>>     obj << "hi"
>>> I still wouldn't call this pass by reference (see my earlier post in
>> irb(main):007:0>
>
> I'm not sure that demonstrates the "values that are references" thing,
> though.  You're reassigning to x in foo, which creates a new local x;
> but I think that's just part of the assignment semantics.  Or are you
> assuming that if pass by reference were involved, then assignment
> would work differently?
>

*** NEWBIE WARNING ***

I'm entering this thread as it gives me a chance to test my own
understanding.
My apologies if I've missed the mark!

I agree the example doesn't show pass by reference v pass by value. I
think it
shows more about scope.

However, I think what he was trying to show was that if what was being
passed
was the address of the variable in the callers environment, then changes
to
what that variable pointed at would be seen in the callers environment
as well.

i.e.

a = Array.new could look like this

-------
|  a  |        ----------
|  ----------->|Array Obj|
|     |        ----------
-------        Addr = 1000
Addr = 0

Here 'a' holds the value 1000, the address of the array object. This
value
(1000) is stored in location 0. 'a' points to the storage location. In C
it
would be called a pointer, in ruby, its just a variable because yo don't
have
anything else. some would say 'a' is bound to the address 1000, which is
the
start location of an array object.

Some of this confusion about passed by value and passed by reference is
due to
C and how it worked. In C, by default, things are passed by value, but
you can
only pass 'simple/base' types. Passing by value has the disadvantage
that it can
have considerable overhead as the data being passed has to be copied and
you
cannot modify the data such that the modifications exist after the
procedure
terminates - modifications are local to the procedure because you are
operating
on a local copy.

However, what people often miss is that, depending on the
implementation, most
of the time, even passing a reference involves a copy. However, as what
you are
copying is the address of the storage location where the data is
located, the
copy operation is independent of the size of the data being referenced -
its
simply a copy of an address and all addresses are essentially the same
size. As
you are copying the address of the storage location, you can reference
that
location from within the procedure and any modifications you make would
affect
that data in the callers environment as well.

Ruby takes a different approach to C. In ruby, all variables are really
references to objects stored somewhwere else. The overheads associated
with
arguement passing are the same regardless of the size or type of object
the
variable references - its just an address. This means the traditional C
pass by
reference and pass by value doesn't really apply in Ruby (or languages
like
Java). All that nasty C referencing and dereferencing is handled under
the hood
and the only ones upset are those clever geeks who use to do all sorts
of
amazing pointer arithmetic that would take us mere mortals hours to
grok.

Now, back to Ruby and the issue of whether the arguments to a procedure
are
truely pass by reference or pass by value. Essentially, I don't think
the
concept really makes sense from the Ruby perspective. However, I guess
it could
be argued that if ruby was pass by reference with respect to arguments,
this
would mean it passes the reference (address) of the variable. In the
above
example, this would be the address of a, which is 0. If it was pass by
value,
it would pass a copy of its contents, which is 1000.

If arguements were pass by reference, changes to what the address
pointed to
would be seen in the callers environment i.e. address 0 would point
somewhere
else. If it is pass by value, changes to what the argument variable
points to
will be lost once the procedure exits and returns to the calling
environment
because the argument is a copy. so

a = Array.new ------> Address 0 holds the value 1000, the address of the
array.
def foo(b)
  b = Array.new -------> b points to array object at address 2000 (new
array obj)
end

 If ruby was pass by reference, the address of a and b wold be the same
i.e. 0.
 If it is pass by value, it would be different.

If a and b have the same address (i.e. 0) then after foo(a), a will
boint at
the second array object (ie. contain address 2000).

Again, in languages like Ruby and Java, the by reference v by value
really
doesn't make much sense because variables all hold references to the
data
rather than holding the data directly. Generally, as conceptually (with
respect
to argument passing), it is convenient to think of Ruby arguments as
pass by
reference, but if you want to be really technically accurate, its pass
by
value.

So, how successfully has that been at muddying the water? Everyone now
nicely
confused?

Tim
Tim X (Guest)
on 2007-01-28 10:35
(Received via mailing list)
Wolfgang Nádasi-Donner <removed_email_address@domain.invalid> writes:

>>>>>> Code >>>>>
>
> def modifying(a_param)
>   a_param = "hi"
> end
>
> def modifying2(a_param=a_value)
>   a_param = "hi"
> end
>

In both the above cases, you are creating new objects that are only
pointed to
by the variable a_param. Initially, that variable is referencing the
same
object as the argument passed to the call. Effectively, you are chaging
what is
being referenced.


> def modifying3(a_param)
>   a_param[0..-1]= "hi"
> end

this one is different. You are changing the value of the object that the
argument references. You are not changing what is referenced.

> end
> end
> end
> because the value of the actual parameter is assigned to the local variable
> used as a formal parameter.
>
> except for "Fixnum" etc. this is a pointer to an object. I one changes the
> object itself, it will work like  "by reference", otherwise only the local
> variable is affected, without having any effect to the outside world.
>

I don't think your example shows what you believe it is showing.
However, to
some extent, this is because the pass by value and pass by reference is
irrelevant in a language like Ruby. What your example shows is the
effect of
changing what a variable points to within a function compared to
changing the
contents of what is pointed to, it doesn't really show differences in
the
traditional pass by value/pass by reference sense. I would argue that in
each
of the cases you have shown, the arguments are passed by value, but the
value
being passed is a reference to an object. In the first two, you change
that
reference, but as it was passed by value, it does not affect the callers
environment. In the third one, you are changing the object that is being
referenced and therefore the change is also visible to the calling
environment.
However, the actual arguments were all passed by value.

Tim
Robert D. (Guest)
on 2007-01-28 10:49
(Received via mailing list)
On 1/28/07, Tim X <removed_email_address@domain.invalid> wrote:
>
> <snip>
> I don't think your example shows what you believe it is showing. However,
> to
> some extent, this is because the pass by value and pass by reference is
> irrelevant in a language like Ruby.


I could not agree  less, very simply because the two sentences
* In ruby a variable is a reference to an object
* All parameters are passed by value
define the whole semantic of  parameters passed to methods(1), no need
for
fancy boxes (though that is always good)
or to look at the implementation (but I had a close look before making
bold
statements like these;)

(1) and that within well accepted computer science jargon
<snip>
>
>
> Tim
>
> --
> tcross (at) rapttech dot com dot au
>
>
Robert
Parragh S. (Guest)
on 2007-01-28 10:51
(Received via mailing list)
Xavier N. wrote:
> Java is pass-by-value for instance (according to the JLS) and that
> test passes.
Could you point me to the exact locus?

Thx:
Szab
unknown (Guest)
on 2007-01-28 11:15
(Received via mailing list)
>>>>
>>>>
>>>> In this example, arr contains a reference to an array.  In change_me,
>>> irb(main):005:0> def bar; x = 20; foo(x); x end
>>
>
>
> would be called a pointer, in ruby, its just a variable because yo don't
> have
> anything else. some would say 'a' is bound to the address 1000, which is
> the
> start location of an array object.
>
> Some of this confusion about passed by value and passed by reference is
> due to
> C and how it worked. In C, by default, things are passed by value

<snip>

> Ruby takes a different approach to C. In ruby, all variables are really
> references to objects stored somewhwere else. The overheads associated
> with
> arguement passing are the same regardless of the size or type of object
> the
> variable references - its just an address. This means the traditional C
> pass by
> reference

I think those statements were informal, but just for the archives C only
has pass-by-value.

Sometimes people think that, say, modifying an integer through a pointer
argument shows pass-by-reference. But it doesn't, the argument is the
pointer there, and is passed by value.

-- fxn
unknown (Guest)
on 2007-01-28 11:26
(Received via mailing list)
> Xavier N. wrote:
>> Java is pass-by-value for instance (according to the JLS) and that
>> test passes.
> Could you point me to the exact locus?

Sure, that's section 8.4.1 in the current edition[*]:

"When the method or constructor is invoked (§15.12), the values of the
actual argument expressions initialize newly created parameter
variables,
each of the declared Type, before execution of the body of the method or
constructor. The Identifier that appears in the DeclaratorId may be used
as a simple name in the body of the method or constructor to refer to
the
formal parameter."

-- fxn

[*]
http://java.sun.com/docs/books/jls/third_edition/h...
Julian T. (Guest)
on 2007-01-28 11:38
(Received via mailing list)
On Jan 27, 2007, at 12:27 AM, Andy K. wrote:

> Is there a way to pass variables by reference into function.
>
> I have large string to pass and the pass by value seems to be
> eating up too much memory.

Strings are mutable objects and should be treated as such :-)

def append_sour_word(strbuf)
   strbuf << " ...uck!"
end

text = "Good l"

append_sour_word(text) #=> "Good luck" is returned AND is contained
in text now
text #=> "Good luck"

def assign_concatenated(strbuf)
   strbuf = strbuf + " ...uck!"
end

assign_concatenated(text) #=> "This is some new text" is returned but
you lost the reference inside the function scope so the actual
_value_ stays the same
text #=> still "Good luck", because you assigned another reference to
your variable

def replace_content(strbuf)
   strbuf.replace(strbuf + " ...uck!")
end

replace_content(text) "Good l..uck!..uck!", but now with a desired
side effect

text #=> "Good l..uck!..uck!", now you replaced the object with
another one

Basically, to avoid confusion - if you eating up RAM avoid object
_duplication_, because that's what eats it up. But it's perfectly
possible to
massage objects in place without having to ask them for their "actual
value".
Grant H. (Guest)
on 2007-01-28 13:50
(Received via mailing list)
On Jan 27, 5:34 am, Wolfgang Nádasi-Donner 
<removed_email_address@domain.invalid>
wrote:
>  >>>>> Code >>>>>
>
> def modifying(a_param)
>    a_param = "hi"
> end
>
> def modifying2(a_param=a_value)
>    a_param = "hi"
> end

In these two methods, the = sign is an assignment, which changes the
memory location of the lvalue to point to the object of the rvalue.

> def modifying3(a_param)
>    a_param[0..-1]= "hi"
> end

This is actually a method call. It could also be written a_param.
[]=(0..-1, "hi") . So the difference is that in this example you are
actually calling a method on the object that a_param points to. This
is due to the syntactic sugar Ruby gives to the method named []= which
in this case is defined on String. See http://www.ruby-doc.org/docs/
ruby-doc-bundle/Manual/man-1.4/syntax.html#assign

So in all three we are passing by value as you define it.
SonOfLilit (Guest)
on 2007-01-28 14:57
(Received via mailing list)
How about:

class Vault
  attr_accessor :unvault
  def initialize val
    @unvault = val
  end
end

class Object
  def to_vault
    Vault.new(self)
  end
end

def change_me(obj)
  obj.unvault += " rocks!"
end

o = "Ruby".to_vault
change_me(o)
p o.unvault

$ ruby vault-test.rb
"Ruby rocks!"
Parragh S. (Guest)
on 2007-01-28 15:23
(Received via mailing list)
removed_email_address@domain.invalid írta:
> "When the method or constructor is invoked (§15.12), the values of the
> actual argument expressions initialize newly created parameter variables,
> each of the declared Type, before execution of the body of the method or
> constructor. The Identifier that appears in the DeclaratorId may be used
> as a simple name in the body of the method or constructor to refer to the
> formal parameter."
>

Thanks a lot, I was curious about this official description for a while!

What I miss, however, is the explicit use of the "pass by value"
expression. Bruce Eckel mentions in Thinking in Java, that both sides of
the controversy have lots of propagators. Both the "everything is pass
by value" theory, and the contrary one that he descrbes as:

"2. Java passes primitives by value (no argument there), but objects
are passed by reference. This is the world view that the reference is
an alias for the object, so you don't think about passing references,
but instead say "I'm passing the object." Since you don't get a local
copy of the object when you pass it into a method, objects are
clearly not passed by value. There appears to be some support for
this view within Sun, since at one time, one of the "reserved but not
implemented" keywords was byvalue (This will probably never be
implemented)."

What is suprising is the reference (:-)) to Sun in this context, if the
JLS says otherwise.

Anyways, this is not a Java list, so sorry for beeing a bit offtopic --
I just hope it helps to show, there's a great mess of notions around
this topic everywhere.

Bye:
Szab
Austin Z. (Guest)
on 2007-01-29 02:10
(Received via mailing list)
On 1/28/07, Thomas H. <removed_email_address@domain.invalid> wrote:
> "Austin Z." <removed_email_address@domain.invalid> wrote/schrieb 
<removed_email_address@domain.invalid>:
> > The simplest way to remember this is that variables in Ruby aren't
> > chunks of memory.
> Or: they are a chunk of memory, but the only kind of value they can
> contain is a reference to an object. A variable is not such an object,
> i.e. there are no references to variables.

It's better not to consider variables in Ruby as anything but a label
and as such *not* a chunk of memory. Chunks of memory suggest object
status or possibilities; this is not part of Ruby.

Your graphs are pretty close to correct. I have to finish some
articles talking about variables in Ruby and post them at some point.

-austin
Austin Z. (Guest)
on 2007-01-29 02:13
(Received via mailing list)
On 1/28/07, Tim X <removed_email_address@domain.invalid> wrote:
> So, how successfully has that been at muddying the water? Everyone now nicely
> confused?

Your description seems to be okay, but forget "address" when dealing
with Ruby variables. It's not an appropriate concept and only muddies
the waters unnecessarily.

-austin
Austin Z. (Guest)
on 2007-01-29 02:16
(Received via mailing list)
On 1/28/07, Grant H. <removed_email_address@domain.invalid> wrote:
> > end
>
> In these two methods, the = sign is an assignment, which changes the
> memory location of the lvalue to point to the object of the rvalue.

When talking about Ruby variables, it is ALWAYS incorrect to refer to
a "memory location." It's not a concept that has any useful meaning in
Ruby. Ever.

-austin
This topic is locked and can not be replied to.