Pass by reference?

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 :slight_smile:

David

“Phrogz” [email protected] wrote/schrieb
[email protected]:

On Jan 26, 4:32 pm, Vincent F. [email protected]
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

On 1/26/07, Vincent F. [email protected] 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

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

On 1/27/07, [email protected] [email protected] 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 :slight_smile:

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

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

Robert

On 1/27/07, Robert D. [email protected] 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 :wink:
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

On 1/27/07, Robert D. [email protected] 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 :wink:
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

SORRY folks my gmail went amok!!!

Xavier N. [email protected] wrote/schrieb
[email protected]:

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

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

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

“Austin Z.” [email protected] wrote/schrieb
[email protected]:

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

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

[email protected] 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

On 1/28/07, Tim X [email protected] wrote:

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

Tim


tcross (at) rapttech dot com dot au

Robert

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

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

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

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/html/classes.html#8.4.1

Wolfgang Nádasi-Donner [email protected] 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

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 :slight_smile:

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”.