Pass by reference or pass by value

Well, try to google the definition of pass-by-reference semantics.
If a language is a object-oriented language, it doesn’t mean
automatically
that you can define methods with pass-by-reference arguments. Also
immutability of some objects has nothing to do with pass-by-reference
semantics.

For example, Java has objects, but it has strong pass-by-value
semantics.

I think we are talking about the same thing, but our definition of
pass-by-reference is a little bit off.

Cheers,
Kent.

On 7/12/2005, at 11:32 AM, Kent S. wrote:

I think we are talking about the same thing, but our definition of
pass-by-reference is a little bit off.

You are quite correct, in those terms Ruby is strictly pass-by-value,
though as you can only pass objects around it isn’t really much of a
restriction.


Phillip H.
[email protected]

i think you meant to say:

m = 4
puts change(m) >> 5
puts m >> 4 (i want to change this to 5)

(note the change(4) is now change(m))
assuming that i understand what you want to be doing and depending on
the situation, one way would be to do this:

def change(n)
n += 1 #just to have it actually do something
end

m = 4
m = change(m)
puts m >> 5

On 8/12/2005, at 1:46 AM, Vivek K. wrote:

I am a bit confused…so how does one implement a function in ruby
which azctually modifies the parameter?

You don’t. I’m not sure what’s wrong with:

def change(i)
i += 1
end

i = 1
i = change(i)

If you need to return multiple values just use an array.


Phillip H.
[email protected]

I am a bit confused…so how does one implement a function in ruby which
azctually modifies the parameter?
how do i make the below code change the value of m?

def change(n)
n.ref = 5
end

m = 4
puts change(4) >> 5
puts m >> 4 (i want to change this to 5)
thanks
vivek

Phillip H. wrote:

i += 1
^^^^^^ didn’t you mean: i + 1 ?
=====

On 8/12/2005, at 12:13 PM, Justin F. wrote:

def change(i)
i += 1
^^^^^^ didn’t you mean: i + 1 ?
=====
end

It’ll still work, just with a redundant assignment. I was early and I
was lacking coffee :wink:


Phillip H.
[email protected]

I just used a simplistic example but what about something like a more
complex function?

checkStatus(statusCode) //returns an boolean true or false and sets
statusCode

how does one implement something like this? should we use arrays?

On 8/12/2005, at 4:31 PM, Vivek K. wrote:

checkStatus(statusCode) //returns an boolean true or false and
sets statusCode

how does one implement something like this? should we use arrays?

Yes, arrays are your friend.

def check_status
[true, 50]
end

result, status_code = check_status


Phillip H.
[email protected]

What about this (to throw a wrench into things)

class Fixnum

def numcalls
@numcalls ||= 0
@numcalls += 1
end

end

irb(main):010:0> 4.numcalls
=> 1
irb(main):011:0> 4.numcalls
=> 2
irb(main):012:0> 4.numcalls
=> 3
irb(main):013:0> 4.numcalls
=> 4
irb(main):014:0> (3+1).numcalls
=> 5

…It would appear that all instances of the number 4 are really the
same. What?

Matz used some pretty devious tricks to cram a lot of potential values
into a 32 bit integer type. VALUE is…

a reference to an object OR
a reference to a primitive (array, hash, float, omaybe more?) OR
a 24 bit symbol table index OR
nil OR
true OR
false OR
undef OR
a 31 bit integer

Values which don’t have an associated GC’d memory blob keep their
“instance data” in a special hash table keyed by their object
reference which is squeezed into the ivar routines in the interpreter
implementation. This includes nil, true, false, symbols, and fixnums,
as best as I can tell (it’s been a few months since I’ve dug around
this code).

You could dynamically construct a symbol three different ways and so
long as they == eachother, they would behave as one object instance.

That said, ruby passes by reference (i.e. changes to the objects’
ivars persist across function call lines), but doesn’t have output
parameters (i.e. the reference is cimmutable) or reference types
(which would let you implement output parameters, as with pointers in
C).

Of course you could build yourself a reference type (Ref = Struct.new
:obj) and pass those around, but no one really does that and hopefully
it’s not too hard to see why not. Multiple returns can be accomplished
via hashes and arrays, which mostly removes the need for output
parameters and is often cleaner.

Brian

On 12/8/05, Phillip H. [email protected] wrote:

def check_status


Rails mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails


The years ahead pick up their dark bags.
They move closer. There’s a slight rise in the silence

then nothing.

(If you’re receiving this in response to mail sent to
[email protected], don’t be concerned This is my new address,
but mail will be forwarded here indefinitely)

I got it, I go it, I got it!!!

def change str
str.replace ‘…’
end

str = ‘.’
change str
puts str

#=> …

yey!

this should be inherited from kernel/Object and then overriden
so a clear interface can be followed, my personal belief.

On 7-dec-2005, at 13:46, Vivek K. wrote:

puts m >> 4 (i want to change this to 5)
Ruby MOSTLY uses “pass by reference” (in PHP-speak), but it also
returns from the last expression (and you can use the returned result).

It’s not possible to change objects outside of scope with Fixnums
(see the thread above) and surely not possible with Symbols, but
possible with all other objects that support Object#bang! methods
(actually all objects that support Object#replace)

def process_text_inside(text)
text.gsub!(/a/, ‘b’)
end

some_text = ‘blabla’

process_text_inside(some_text)

some_text #=> 'blbblb;

def replace_text_inside(text)
text.replace(“foo”) # you have to pass an object of the same class,
otherwise you get a TypeError
end

replace_text_inside(some_text)

some_text #=> ‘foo’

If you explicitly need to modify the passed value without modifying
the passed variable (you will shoot yourself in the foot if you do so
unintentionally), use Object#dup.

Please read PickAxe, you are missing some fundamental Ruby basics.
And never name your variable statusCode.


Julian ‘Julik’ Tarkhanov
me at julik.nl

Kazuyoshi T. wrote:

I got it, I go it, I got it!!!

def change str
str.replace ‘…’
end

str = ‘.’
change str
puts str

#=> …

yey!

(Hey guys, I realize this thread is a month old, but its relevant to
something I’m doing right now.)

Wow, this is the first time I’ve been disappointed by Ruby. This seems
to me to be a very poor choice. This (real code)…

string = ‘a string’
copy = string
string.replace ‘a different string’

…seems a very poor substitute for this (pseudocode), which I would
expect to have the same result…

string = ‘a string’
copy = *string
string = ‘a different string’

…because the real code requires the changer of the string to know that
there is going to be a copy made of the string. Here’s a more realistic
example (assume Person is a class that allows new instance variables to
be created at runtime; in fact, I have completely implemented such a
Person class and the irb I/O shown is completely real):

irb> p = Person.new
=> #<Person:0x2bc43d0 @field_list=[:first_name, :last_name,
:middle_name, :location, :primary_email, :primary_phone_number]>
irb> p.personal_email = ‘[email protected]
=> “[email protected]
irb> p
=> #<Person:0x2bc43d0 @personal_email=“[email protected]”,
@field_list=[:first_name, :last_name, :middle_name, :location,
:primary_email, :primary_phone_number, :personal_email]>
irb> p.primary_email = p.personal_email
=> “[email protected]
irb> p
=> #<Person:0x2bc43d0 @personal_email=“[email protected]”,
@primary_email=“[email protected]”, @field_list=[:first_name, :last_name,
:middle_name, :location, :primary_email, :primary_phone_number,
:personal_email]>
irb> p.personal_email.replace ‘[email protected]
=> “[email protected]
irb> p
=> #<Person:0x2bc43d0 @personal_email=“[email protected]”,
@primary_email=“[email protected]”, @field_list=[:first_name, :last_name,
:middle_name, :location, :primary_email, :primary_phone_number,
:personal_email]>

Is there really no way to do this such that the line
“p.personal_email.replace ‘[email protected]’” can be replaced with
“p.personal_email = ‘[email protected]’” and both strings will be modified?
I think that’s terrible–obviously, it’s pretty realistic to expect that
code like this would occur, but making it possible it requires every
piece of code that changes p.personal_email to know that there is or
could be a copy of it made. It makes String.= virtually useless,
because in order to make it possible for a user to create a new String
that always reflects the contents of another String, one must always use
String.replace instead of String.= to assign values to Strings. It
seems like the best solution would simply be to add an =* operator (to
Object itself, ideally) such that this would be possible, in place of
the line “p.primary_email = p.personal_email” above:

p.primary_email =* p.personal_email #p.primary_email now contains a
pointer directly to p.personal_email instead of containing a pointer to
the same object that p.personal_email points to

Of course, that is easier said than done, but I can’t think of any other
solution that comes close to being as elegant.

Am I missing something? Is there already a way to create pointers to
pointers in Ruby so that this problem can be avoided?

Thanks,
Doug

string = ‘a string’
copy = string
string.replace ‘a different string’

…because the real code requires the changer of the string to know that
there is going to be a copy made of the string.

For me, Object#clone or Object#dup works:

string = ‘a string’
copy = string.clone
string = ‘a different string’