Question - Passing parameters by reference

Hello Folks

My question is the following:

How can I pass a reference to a method as an argument, so after
finishing the execution of the method the argument gets updated with a
new value. ( known as "pass by reference" in other languages ).

example:
....
def changeValue( val, cad )
     temp = 0;
     val = (val * 10) / cad.to_i
     temp = cad.to_i + 3.to_i
     cad = temp.to_s
end
....
....
val = 35;
cad = "7"

puts "val before calling changeValue:= " + val.to_s
puts "cad before calling changeValue:=" + cad

changeValue( val, cad )

puts "val before calling changeValue:= " + val.to_s #--- I pretend
to print '50'
puts "cad before calling changeValue:=" + cad #--- I pretend
to print '10'

Regards
Carlos

Assignment inside method scope is allowed, but creates a different
object. What you get back from a method is what the method returns.
So you could mimic your desired behavior with...

def f(a, b)
  return a*10.0/b.to_i, (b.to_i+3).to_s
end

x, y = 35, "7"
x, y = f( x, y ) #this will make x equal to 50 and y equal to the string "10"

Does that make sense?

Todd

···

On 7/25/07, caof2005 <caof2005@gmail.com> wrote:

Hello Folks

My question is the following:

How can I pass a reference to a method as an argument, so after
finishing the execution of the method the argument gets updated with a
new value. ( known as "pass by reference" in other languages ).

example:
....
def changeValue( val, cad )
     temp = 0;
     val = (val * 10) / cad.to_i
     temp = cad.to_i + 3.to_i
     cad = temp.to_s
end
....
val = 35;
cad = "7"

puts "val before calling changeValue:= " + val.to_s
puts "cad before calling changeValue:=" + cad

changeValue( val, cad )

puts "val before calling changeValue:= " + val.to_s #--- I pretend
to print '50'
puts "cad before calling changeValue:=" + cad #--- I pretend
to print '10'

Regards
Carlos

to have to return the changed value? How do you pass in a variable to a
method and have the change stick when it exists the method in ruby?
Chris

···

On 7/25/07, Todd Benson <caduceass@gmail.com> wrote:

On 7/25/07, caof2005 <caof2005@gmail.com> wrote:
> Hello Folks
>
> My question is the following:
>
> How can I pass a reference to a method as an argument, so after
> finishing the execution of the method the argument gets updated with a
> new value. ( known as "pass by reference" in other languages ).
>
> example:
> ....
> def changeValue( val, cad )
> temp = 0;
> val = (val * 10) / cad.to_i
> temp = cad.to_i + 3.to_i
> cad = temp.to_s
> end
> ....
> val = 35;
> cad = "7"
>
> puts "val before calling changeValue:= " + val.to_s
> puts "cad before calling changeValue:=" + cad
>
> changeValue( val, cad )
>
> puts "val before calling changeValue:= " + val.to_s #--- I pretend
> to print '50'
> puts "cad before calling changeValue:=" + cad #--- I pretend
> to print '10'
>
> Regards
> Carlos

Assignment inside method scope is allowed, but creates a different
object. What you get back from a method is what the method returns.
So you could mimic your desired behavior with...

def f(a, b)
  return a*10.0/b.to_i, (b.to_i+3).to_s
end

x, y = 35, "7"
x, y = f( x, y ) #this will make x equal to 50 and y equal to the string
"10"

Does that make sense?

Todd

What if the method is returning something else already and you don't want

Todd:

Although it did not change neither of both parameters and I suppose
you can't do this in Ruby, at the end you showed me a new technique
that can mimic the behavior.

Thanks so much for this tip!!!

Carlos

···

On Jul 25, 10:54 am, "Todd Benson" <caduce...@gmail.com> wrote:

On 7/25/07, caof2005 <caof2...@gmail.com> wrote:

> Hello Folks

> My question is the following:

> How can I pass a reference to a method as an argument, so after
> finishing the execution of the method the argument gets updated with a
> new value. ( known as "pass by reference" in other languages ).

> example:
> ....
> def changeValue( val, cad )
> temp = 0;
> val = (val * 10) / cad.to_i
> temp = cad.to_i + 3.to_i
> cad = temp.to_s
> end
> ....
> ....
> val = 35;
> cad = "7"

> puts "val before calling changeValue:= " + val.to_s
> puts "cad before calling changeValue:=" + cad

> changeValue( val, cad )

> puts "val before calling changeValue:= " + val.to_s #--- I pretend
> to print '50'
> puts "cad before calling changeValue:=" + cad #--- I pretend
> to print '10'

> Regards
> Carlos

Assignment inside method scope is allowed, but creates a different
object. What you get back from a method is what the method returns.
So you could mimic your desired behavior with...

def f(a, b)
  return a*10.0/b.to_i, (b.to_i+3).to_s
end

x, y = 35, "7"
x, y = f( x, y ) #this will make x equal to 50 and y equal to the string "10"

Does that make sense?

Todd

Hi --

What if the method is returning something else already and you don't want
to have to return the changed value? How do you pass in a variable to a
method and have the change stick when it exists the method in ruby?

You can change an object:

   def change_me(str)
     str.upcase!
   end

   s = "abc"
   change_me(str)
   puts s # ABC

But you can't change the bindings. In the example, I've got s and str
both containing references to the same string. But the names of the
identifiers themselves, s and str, are solely the business of their
local scopes, which are different as between the method body and the
calling context.

David

···

On Thu, 26 Jul 2007, Chris Thiel wrote:

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

def add_one(number)
number+=1
end
n = 1
add_one(n)

While the method returns 2, the value of n when the method is done is still
one.

Or with strings
def add_bar(st)
st + "bar"
end

s = "foo"
add_bar(s)

Same thing. The method returns foobar, but the value of s is unchaged.
Is there a way to change the values of these variables from within the
method and have the values remain changed when the method has exited?

Chris

···

On 7/25/07, dblack@wobblini.net <dblack@wobblini.net> wrote:

Hi --

On Thu, 26 Jul 2007, Chris Thiel wrote:

> What if the method is returning something else already and you don't
want
> to have to return the changed value? How do you pass in a variable to a
> method and have the change stick when it exists the method in ruby?

You can change an object:

   def change_me(str)
     str.upcase!
   end

   s = "abc"
   change_me(str)
   puts s # ABC

But you can't change the bindings. In the example, I've got s and str
both containing references to the same string. But the names of the
identifiers themselves, s and str, are solely the business of their
local scopes, which are different as between the method body and the
calling context.

David

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

I'm talking in a case like this:

What if the method is returning something else already and you don't want
to have to return the changed value? How do you pass in a variable to a
method and have the change stick when it exists the method in ruby?

You can change an object:

def change_me(str)
   str.upcase!
end

s = "abc"

did you mean to say...

    s = str = "abc"

?

···

On Thu, 26 Jul 2007, Chris Thiel wrote:

change_me(str)
puts s # ABC

But you can't change the bindings. In the example, I've got s and str
both containing references to the same string. But the names of the
identifiers themselves, s and str, are solely the business of their
local scopes, which are different as between the method body and the
calling context.

David

--
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
   & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

Thanks for the response, although I was just wondering that using
Strings as a parameters in a method definition is a special case.
Let me explain....
    I observed that when you use a string as a parameter in a method
definition, it can be changed by applying several operations inside
the method, for instance you can change it, by adding letters to the
string, changing the content to uppercase etc.
So I figured out that when you use a string, what really happens
inside the method is that you don't create a new object, you just use
the reference.
    In opposition as if you use other kind of parameters in a method
definition, let say for example an int variable.
    If you try to change this int variable inside the method, it
simply doesn't work, what happens is that you get a "copy" of the
object that you're passing but after the method is finished, that
copy disappears and at the end the parameter that you passed was not
affected.
Am I correct with my conclusions?

Regards
Carlos

···

On Jul 25, 11:35 am, dbl...@wobblini.net wrote:

Hi --

On Thu, 26 Jul 2007, Chris Thiel wrote:
> What if the method is returning something else already and you don't want
> to have to return the changed value? How do you pass in a variable to a
> method and have the change stick when it exists the method in ruby?

You can change an object:

   def change_me(str)
     str.upcase!
   end

   s = "abc"
   change_me(str)
   puts s # ABC

But you can't change the bindings. In the example, I've got s and str
both containing references to the same string. But the names of the
identifiers themselves, s and str, are solely the business of their
local scopes, which are different as between the method body and the
calling context.

David

--
* Books:
   RAILS ROUTING (new!http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

I believe it's adding & in front of the argument in a method in C++ to get
pass by reference.
void add_one(&num) {
num++
}

Is there something that's equivalent in ruby?

Chris

n = add_one(n) would fix your given case. I assume it is more complicated
than this?

···

On 7/25/07, Chris Thiel <ccthiel@gmail.com> wrote:

On 7/25/07, dblack@wobblini.net <dblack@wobblini.net> wrote:
>
> Hi --
>
> On Thu, 26 Jul 2007, Chris Thiel wrote:
>
> > What if the method is returning something else already and you don't
> want
> > to have to return the changed value? How do you pass in a variable to
a
> > method and have the change stick when it exists the method in ruby?
>
> You can change an object:
>
> def change_me(str)
> str.upcase!
> end
>
> s = "abc"
> change_me(str)
> puts s # ABC
>
> But you can't change the bindings. In the example, I've got s and str
> both containing references to the same string. But the names of the
> identifiers themselves, s and str, are solely the business of their
> local scopes, which are different as between the method body and the
> calling context.
>
> David
>
> --
> * Books:
> RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
> RUBY FOR RAILS (http://www.manning.com/black\)
> * Ruby/Rails training
> & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
>
> I'm talking in a case like this:
def add_one(number)
number+=1
end
n = 1
add_one(n)

While the method returns 2, the value of n when the method is done is
still
one.

Or with strings
def add_bar(st)
st + "bar"
end

s = "foo"
add_bar(s)

Same thing. The method returns foobar, but the value of s is unchaged.
Is there a way to change the values of these variables from within the
method and have the values remain changed when the method has exited?

Chris

--
"Hey brother christian with your high and mighty errand, Your actions speak
so loud, I can't hear a word you're saying."

-Greg Graffin (Bad Religion)

Thanks for the response, although I was just wondering that using
Strings as a parameters in a method definition is a special case.
Let me explain....
    I observed that when you use a string as a parameter in a method
definition, it can be changed by applying several operations inside
the method, for instance you can change it, by adding letters to the
string, changing the content to uppercase etc.
So I figured out that when you use a string, what really happens
inside the method is that you don't create a new object, you just use
the reference.
    In opposition as if you use other kind of parameters in a method
definition, let say for example an int variable.
    If you try to change this int variable inside the method, it
simply doesn't work, what happens is that you get a "copy" of the
object that you're passing but after the method is finished, that
copy disappears and at the end the parameter that you passed was not
affected.
Am I correct with my conclusions?

Regards
Carlos

Yes, because a Fixnum object is immutable. Also, like David said, you
cannot change bindings. See...

def f x; x = 6; end

=> nil

a = 1

=> 1

f a

=> 6

a

=> 1

Now look at something that is mutable, like String...

a = "hello"

=> "hello"

def g x; x << "bye"; end

=> nil

f a

"hellobye"

a

"hellobye"

But watch this assignment...

a = "hello"

=> "hello"

a.__id__

=> 68099810

def g x
  puts x.__id__
  x = "bye" #here is an attempt at assignment
  puts x.__id__ #oops, not correct scope, created new string

object with name x

end

=> nil

g a

68099810
68052050
=> nil

a #should be unchanged

=> "hello"

So yes, mutable objects you can change within method scope, but not
reassign. To answer Chris's question about what you should do when
you are already returning something, well, you can return more than
one thing. You can also send an object as a parameter (Array, Hash,
whatever), which of course can be modified within the method.

cheers,
Todd

···

On 7/25/07, caof2005 <caof2005@gmail.com> wrote:

You're pretty close, just some details as to the whyness:

String are of course instances of the String class. This is simply an array
of characters, of which you can modify freely, as you've discovered.

Numbers, on the other hand are special case instances of FixNum, BigNumber,
any subclass of Numeric. These have no underlying data representation, they
*are* the number they represent. So if you tried to do the same to Fixnums
like you can with String, you'd actually be trying to change 1 to equal 2,
and you can imagine what kind of havok that would cause.

So with Strings, you have an underlying character array you can play with,
but with Numerics you have to change the number your variable is pointing
to.

Hopefully I made that understandable, though please correct me if something
I said was wrong.

Jason

···

On 7/25/07, caof2005 <caof2005@gmail.com> wrote:

Thanks for the response, although I was just wondering that using
Strings as a parameters in a method definition is a special case.
Let me explain....
    I observed that when you use a string as a parameter in a method
definition, it can be changed by applying several operations inside
the method, for instance you can change it, by adding letters to the
string, changing the content to uppercase etc.
So I figured out that when you use a string, what really happens
inside the method is that you don't create a new object, you just use
the reference.
    In opposition as if you use other kind of parameters in a method
definition, let say for example an int variable.
    If you try to change this int variable inside the method, it
simply doesn't work, what happens is that you get a "copy" of the
object that you're passing but after the method is finished, that
copy disappears and at the end the parameter that you passed was not
affected.
Am I correct with my conclusions?

Regards
Carlos

On Jul 25, 11:35 am, dbl...@wobblini.net wrote:
> Hi --
>
> On Thu, 26 Jul 2007, Chris Thiel wrote:
> > What if the method is returning something else already and you don't
want
> > to have to return the changed value? How do you pass in a variable to
a
> > method and have the change stick when it exists the method in ruby?
>
> You can change an object:
>
> def change_me(str)
> str.upcase!
> end
>
> s = "abc"
> change_me(str)
> puts s # ABC
>
> But you can't change the bindings. In the example, I've got s and str
> both containing references to the same string. But the names of the
> identifiers themselves, s and str, are solely the business of their
> local scopes, which are different as between the method body and the
> calling context.
>
> David
>
> --
> * Books:
> RAILS ROUTING (new!http://www.awprofessional.com/title/0321509242\)
> RUBY FOR RAILS (http://www.manning.com/black\)
> * Ruby/Rails training
> & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

Hi --

···

On Thu, 26 Jul 2007, Philip Hallstrom wrote:

On Thu, 26 Jul 2007, Chris Thiel wrote:

What if the method is returning something else already and you don't want
to have to return the changed value? How do you pass in a variable to a
method and have the change stick when it exists the method in ruby?

You can change an object:

def change_me(str)
   str.upcase!
end

s = "abc"

did you mean to say...

  s = str = "abc"

?

change_me(str)

No; I meant to say change_me(s) :slight_smile:

David

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

Chris Thiel wrote the following on 25.07.2007 20:56 :

I believe it's adding & in front of the argument in a method in C++ to get
pass by reference.
void add_one(&num) {
num++
}

Is there something that's equivalent in ruby?

Ruby always pass references. The problem is that "number += 1" is expanded as "number = number + 1".

The problem here is that Fixnum#+ doesn't modify the object but generates another one. So in fact it generates what happens is that a new Object is created and then is referenced by number, but not by n. To make it work like you want you would need to only use methods that modify the object itself, which AFAIR don't exist in this context.

Lionel.

I think it's the clearest explanation so far Jason.

I believe it's a good practice to stop thinking in terms of pointers
and start thinking in terms of objects.
You don't pass a variable by reference, you pass an object.

With a little time you'll find this approach a lot more comfortable.

Cheers !

···

On 25/07/07, Jason Roelofs <jameskilton@gmail.com> wrote:

You're pretty close, just some details as to the whyness:

String are of course instances of the String class. This is simply an array
of characters, of which you can modify freely, as you've discovered.

Numbers, on the other hand are special case instances of FixNum, BigNumber,
any subclass of Numeric. These have no underlying data representation, they
*are* the number they represent. So if you tried to do the same to Fixnums
like you can with String, you'd actually be trying to change 1 to equal 2,
and you can imagine what kind of havok that would cause.

So with Strings, you have an underlying character array you can play with,
but with Numerics you have to change the number your variable is pointing
to.

Hopefully I made that understandable, though please correct me if something
I said was wrong.

Jason

On 7/25/07, caof2005 <caof2005@gmail.com> wrote:
>
> Thanks for the response, although I was just wondering that using
> Strings as a parameters in a method definition is a special case.
> Let me explain....
> I observed that when you use a string as a parameter in a method
> definition, it can be changed by applying several operations inside
> the method, for instance you can change it, by adding letters to the
> string, changing the content to uppercase etc.
> So I figured out that when you use a string, what really happens
> inside the method is that you don't create a new object, you just use
> the reference.
> In opposition as if you use other kind of parameters in a method
> definition, let say for example an int variable.
> If you try to change this int variable inside the method, it
> simply doesn't work, what happens is that you get a "copy" of the
> object that you're passing but after the method is finished, that
> copy disappears and at the end the parameter that you passed was not
> affected.
> Am I correct with my conclusions?
>
> Regards
> Carlos
>
> On Jul 25, 11:35 am, dbl...@wobblini.net wrote:
> > Hi --
> >
> > On Thu, 26 Jul 2007, Chris Thiel wrote:
> > > What if the method is returning something else already and you don't
> want
> > > to have to return the changed value? How do you pass in a variable to
> a
> > > method and have the change stick when it exists the method in ruby?
> >
> > You can change an object:
> >
> > def change_me(str)
> > str.upcase!
> > end
> >
> > s = "abc"
> > change_me(str)
> > puts s # ABC
> >
> > But you can't change the bindings. In the example, I've got s and str
> > both containing references to the same string. But the names of the
> > identifiers themselves, s and str, are solely the business of their
> > local scopes, which are different as between the method body and the
> > calling context.
> >
> > David
> >
> > --
> > * Books:
> > RAILS ROUTING (new!http://www.awprofessional.com/title/0321509242\)
> > RUBY FOR RAILS (http://www.manning.com/black\)
> > * Ruby/Rails training
> > & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
>

--
Rusty
http://www.oxidized.com.ar/
okushi@gmail.com

Sorry to derail the thread a bit there.

Chris

···

On 7/25/07, Lionel Bouton <lionel-subscription@bouton.name> wrote:

Chris Thiel wrote the following on 25.07.2007 20:56 :
> I believe it's adding & in front of the argument in a method in C++ to
> get
> pass by reference.
> void add_one(&num) {
> num++
> }
>
> Is there something that's equivalent in ruby?

Ruby always pass references. The problem is that "number += 1" is
expanded as "number = number + 1".

The problem here is that Fixnum#+ doesn't modify the object but
generates another one. So in fact it generates what happens is that a
new Object is created and then is referenced by number, but not by n. To
make it work like you want you would need to only use methods that
modify the object itself, which AFAIR don't exist in this context.

Lionel.

Yup, that's what I was wondering.

Hi --

I think it's the clearest explanation so far Jason.

I believe it's a good practice to stop thinking in terms of pointers
and start thinking in terms of objects.
You don't pass a variable by reference, you pass an object.

Or... you pass a reference by variable :slight_smile: I think it's useful to
know that you're passing references around:

   a = "abc"
   b = a
   b << "def"
   a # "abcdef"

vs. immediate values (symbols, integers), though of course it does all
indeed converge on objects.

David

···

On Thu, 26 Jul 2007, Okushi wrote:

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

I go even farther and simply think of symbols and integers to also be
references. Within that context, the literal 1 is simply a textual
representation of a reference to the object that behaves like the integer 1.
The fact that the Ruby interpreter doesn't actually allocate memory for
the object itself is just an implementation detail.

Gary Wright

···

On Jul 25, 2007, at 4:43 PM, dblack@wobblini.net wrote:

I think it's useful to
know that you're passing references around:

  a = "abc"
  b = a
  b << "def"
  a # "abcdef"

vs. immediate values (symbols, integers), though of course it does all
indeed converge on objects.

Hi --

I think it's useful to
know that you're passing references around:

a = "abc"
b = a
b << "def"
a # "abcdef"

vs. immediate values (symbols, integers), though of course it does all
indeed converge on objects.

I go even farther and simply think of symbols and integers to also be
references. Within that context, the literal 1 is simply a textual
representation of a reference to the object that behaves like the integer 1.
The fact that the Ruby interpreter doesn't actually allocate memory for
the object itself is just an implementation detail.

I'd agree about the literal 1 in comparison with other literals:

   1 # textual representation of that object
   "hi" # textual representation of that object
   [1,2,3] # etc.

but if you do this:

   a = 1
   b = "hi"

now a (as I understand it) is actually bound to the integer 1, while b
is bound to a reference to the object. (I can't say "A reference to
'hi'" since that 'hi' would be a different one.... :slight_smile:

The reason I think it can be good to keep that difference in view is
that it has some explanatory power -- especially when the question
arises about why there's no a++ (which, because a *is* 1, would be
like 1++).

David

···

On Tue, 7 Aug 2007, Gary Wright wrote:

On Jul 25, 2007, at 4:43 PM, dblack@wobblini.net wrote:

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

Hi --

>> I think it's useful to
>> know that you're passing references around:
>>
>> a = "abc"
>> b = a
>> b << "def"
>> a # "abcdef"
>>
>> vs. immediate values (symbols, integers), though of course it does all
>> indeed converge on objects.
>>
>
> I go even farther and simply think of symbols and integers to also be
> references. Within that context, the literal 1 is simply a textual
> representation of a reference to the object that behaves like the
integer 1.
> The fact that the Ruby interpreter doesn't actually allocate memory for
> the object itself is just an implementation detail.

I'd agree about the literal 1 in comparison with other literals:

   1 # textual representation of that object
   "hi" # textual representation of that object
   [1,2,3] # etc.

but if you do this:

   a = 1
   b = "hi"

now a (as I understand it) is actually bound to the integer 1, while b
is bound to a reference to the object. (I can't say "A reference to
'hi'" since that 'hi' would be a different one.... :slight_smile:

The reason I think it can be good to keep that difference in view is
that it has some explanatory power -- especially when the question
arises about why there's no a++ (which, because a *is* 1, would be
like 1++).

If 1 and "hi" were methods, they might look like this:

val = 1
define_method(:one) { val }

define_method(:hi) { val = String.new; val[0] = ?h; val[1] = ?i; val }

a = one()
b = hi()
c = hi()
d = one()

this seemed to illustrate it better in my head. Seeing it typed out, it
doesn't look so insightful. I guess what I'm trying to say is. don't think
of literals as ways of referring to objects, think of them as method calls
that return objects. Or something like that.

David

···

On 8/6/07, dblack@rubypal.com <dblack@rubypal.com> wrote:

On Tue, 7 Aug 2007, Gary Wright wrote:
> On Jul 25, 2007, at 4:43 PM, dblack@wobblini.net wrote:

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)