Forum: Ruby on Rails pass by reference or pass by value

043efdc2a79afbfec84696f50fd42163?d=identicon&s=25 onurturgay (Guest)
on 2005-12-05 21:59
(Received via mailing list)
hi,
I couldnt figure out if ruby works with `pass by value` or `pass by
reference`.. Whats the catch? is it simple types, complex types?

pass by value example:

def hop(onur)
  onur=onur+1
end


ahmet=5
hop(ahmet)
>> ahmet
=> 5

pass by reference example:

def lala(node)
  node.body="hoppa"
end

n= Node.new
lala(n)
n.body
=> "hoppa"
01d7a451018ac15518f425078ef00c40?d=identicon&s=25 sitharus-rails (Guest)
on 2005-12-05 22:07
(Received via mailing list)
On 6/12/2005, at 9:56 AM, Onur Turgay wrote:

> I couldnt figure out if ruby works with `pass by value` or `pass by
> reference`.. Whats the catch? is it simple types, complex types?

Ruby only has objects, so pass by 'value' is nonsensical, there are
only references. Consequently Ruby has no 'simple' types.

However, watch for methods that return new object. int + int returns
a new int, it doesn't modify the value of the old int. That's the
difference between string.gsub and string.gsub! - the latter modifies
the object, the former returns a new string. This pattern is followed
in many of the Ruby libraries.

--
Phillip Hutchings
phillip.hutchings@sitharus.com
043efdc2a79afbfec84696f50fd42163?d=identicon&s=25 onurturgay (Guest)
on 2005-12-05 22:15
(Received via mailing list)
I got it.. thanks a lot.
Ef4d1b20eba4b45b4a477c33bae1d156?d=identicon&s=25 ksibilev (Guest)
on 2005-12-06 06:35
(Received via mailing list)
Well, actually Ruby is 'pass by value' language.

Here is the proof:

irb(main):001:0> def swap(a,b)
irb(main):002:1>   a,b = b,a
irb(main):003:1> end
=> nil
irb(main):004:0> a,b = 1,2
=> [1, 2]
irb(main):005:0> swap a,b
=> [2, 1]
irb(main):006:0> puts a,b
1
2
=> nil

If Ruby were 'pass by reference', a and b variables would be 2 and 1
respectively.

Cheers,
Kent.
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 ara.t.howard (Guest)
on 2005-12-06 07:00
(Received via mailing list)
On Tue, 6 Dec 2005, Kent Sibilev wrote:

> irb(main):005:0> swap a,b
> => [2, 1]
> irb(main):006:0> puts a,b
> 1
> 2
> => nil
>
> If Ruby were 'pass by reference', a and b variables would be 2 and 1
> respectively.


it's more complicated than that.

   harp:~ > cat a.rb
   a = []
   def add list, value
     list << value
   end

   add a, 42

   p a


   harp:~ > ruby a.rb
   [42]


the reason your swap method doesn't work is that cow (copy on write) and
scoping are confusing the issue.

first, ruby uses copy on write so:

   harp:~ > cat a.rb
   a = []
   b = a

   a << 42
   p b
   p a

   b = 'forty-two'
   p b
   p a


   harp:~ > ruby a.rb
   [42]
   [42]
   "forty-two"
   [42]

notice that at first b is 'pointing' to a.  but after it's assigned to
it has a
different value.

so your swap method does this

   def swap(a,b)

# here a and b both refer to the variable passed in

     a,b = b,a

# on the rhs b and a are the passed in values.  on the lhs you introduce
two #
# local variables which, due to copy on write, obtain new values while
preserving
# the orignial a and b

   end

nevertheless, ruby is strictly pass by reference.  for instance, this
swap
method will work fine:

     harp:~ > cat a.rb
     require "yaml"

     def swap a, b
       da, db = a.dup, b.dup
       a.replace db
       b.replace da
       return [ b, a ]
     end

     a, b = "foo", "bar"
     swap a, b

     y "a" => a, "b" => b


     harp:~ > ruby a.rb
     ---
     a: bar
     b: foo

regards.

-a
--
===============================================================================
| ara [dot] t [dot] howard [at] noaa [dot] gov
| all happiness comes from the desire for others to be happy.  all misery
| comes from the desire for oneself to be happy.
| -- bodhicaryavatara
===============================================================================
10d9ed7ab11115b081bb36f56a7a13bc?d=identicon&s=25 johnwilger (Guest)
on 2005-12-06 07:08
(Received via mailing list)
On 12/6/05, Kent Sibilev <ksibilev@gmail.com> wrote:
> Well, actually Ruby is 'pass by value' language.
>
> Here is the proof:

> If Ruby were 'pass by reference', a and b variables would be 2 and 1
> respectively.

Yes and no. When you pass an argument into a method, you are passing a
variable that points to a reference. In a way, it's a combination of
pass by value and pass by reference. What I mean is, you pass the
value of the variable in to the method, however the value of the
variable is _always_ a reference to an object.

The difference between:

  def my_method( a )
    a.gsub!( /foo/, 'ruby' )
  end

  str = 'foo is awesome'
  my_method( str )            #=> 'ruby is awesome'
  str                                    #=> 'ruby is awesome'

and:

  def your_method( a )
    a = a.gsub( /foo/, 'ruby' )
  end

  str = 'foo is awesome'
  my_method( str )            #=> 'ruby is awesome'
  str                                    #=> 'foo is awesome'

is that in #my_method, you are calling #gsub! which changes the object
(a) in place. Since the 'str' variable (outside the method scope) and
the 'a' variable (inside the method scope) both have a "value" that is
a reference to the same object, the change to that object is reflected
in the 'str' variable after the method is called. In #your_method, you
call #gsub which does _not_ modify the original object. Instead it
creates a new instance of String that contains the modifications. When
you assign that object to the 'a' variable, you are changing the value
of 'a' to be a reference to that new String instance. However, the
value of 'str' still contains a reference to the original (unmodified)
string object.

--
Regards,
John Wilger
http://johnwilger.com

-----------
Alice came to a fork in the road. "Which road do I take?" she asked.
"Where do you want to go?" responded the Cheshire cat.
"I don't know," Alice answered.
"Then," said the cat, "it doesn't matter."
- Lewis Carrol, Alice in Wonderland
043efdc2a79afbfec84696f50fd42163?d=identicon&s=25 onurturgay (Guest)
on 2005-12-06 08:37
(Received via mailing list)
just out of curiosity; is there a way that I can increase the value of
an
integer without introducinw Integer objects into the scope?
01d7a451018ac15518f425078ef00c40?d=identicon&s=25 sitharus-rails (Guest)
on 2005-12-06 11:04
(Received via mailing list)
On 6/12/2005, at 8:34 PM, Onur Turgay wrote:

> just out of curiosity; is there a way that I can increase the value
> of an integer without introducinw Integer objects into the scope?

No, you can't modify an integer object. This is a speed optimisation
so that a full object isn't created to run an integer.

--
Phillip Hutchings
phillip.hutchings@sitharus.com
3203ed0e608d3bfae1e31282e629ffa2?d=identicon&s=25 peter.fitzgibbons (Guest)
on 2005-12-06 13:35
(Received via mailing list)
On 12/6/05, Phillip Hutchings <sitharus-rails@sitharus.com> wrote:
> --
> Phillip Hutchings
> phillip.hutchings@sitharus.com
>
>
> _______________________________________________
> Rails mailing list
> Rails@lists.rubyonrails.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>

[Onur] It may be educational to be checking Object#id in the above
examples
(add a bunch of puts to the code).

[John] Try these defs on for size :
With pointers, we can pass the values 'by reference.' Passing by
reference
means that we'll pass the *addresses* of the variables instead of the
values. pass-by-value vs.
pass-by-reference<http://www.cs.princeton.edu/%7Elworthin/126/precep...

--
3203ed0e608d3bfae1e31282e629ffa2?d=identicon&s=25 peter.fitzgibbons (Guest)
on 2005-12-06 13:40
(Received via mailing list)
On 12/6/05, Peter Fitzgibbons <peter.fitzgibbons@gmail.com> wrote:
> >
> > Rails@lists.rubyonrails.org
>
> --
> ------------------------------
> Joyeux Noël
> ------------------------------
> Peter Fitzgibbons
>


[Onur] BTW: Object#id exists for every type in Ruby... since everything
is
an "object" and is inherited from Object!
--
043efdc2a79afbfec84696f50fd42163?d=identicon&s=25 onurturgay (Guest)
on 2005-12-06 16:19
(Received via mailing list)
does that mean integer is not a full object?
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 ara.t.howard (Guest)
on 2005-12-06 16:31
(Received via mailing list)
On Tue, 6 Dec 2005, Onur Turgay wrote:

> does that mean integer is not a full object?

yes.  all variables in ruby are essentially pointers that contain the
address
of their object.  integers are very speical - the whole object __is__
the
pointer - it can be done because ruby uses 31 bits for variables and a
test of
a single bit lets it know if the variable is an integer or a pointer to
object.


-a
10d9ed7ab11115b081bb36f56a7a13bc?d=identicon&s=25 johnwilger (Guest)
on 2005-12-06 17:00
(Received via mailing list)
On 12/6/05, Peter Fitzgibbons <peter.fitzgibbons@gmail.com> wrote:
> [John] Try these defs on for size :
> With pointers, we can pass the values 'by reference.' Passing by reference
> means that we'll pass the addresses of the variables instead of the values.
> pass-by-value vs. pass-by-reference

Yes, I understand the C concepts involved and the difference between
value and reference in that regard (not sure why you think I didn't).
However, I think one of the reasons this is a confusing issue for
people starting with Ruby that actually have previous experience with
C-like languages is that Ruby is not C.

OK, I'm far from an expert on C, and this is based on my
understanding; so if anyone notices any glaring errors, please correct
me.

In C, when you have "int a = 1;", the value of a is 1 (a primitive
type). In Ruby, when you have "a = 1", the value of a is actually a
reference to an instance of Fixnum which represents the integer 1.
Ruby _has_no_primitive_types_ (ok, it's implimented in C, so they do
exist behind the scenes; but there is no way to access a pure
primitive type within your Ruby code).

In C, when you create a variable, you reserve a specific address-space
in memory for that variable. That variable "knows" two things about
itself depending on how you use it (not quite -- this is simplified);
it knows what its value is (what the contents of that memory space
is), and it knows its physical memory address (the pointer). If you
do:

  int a = 1;
  int b = a;

each variable reserves a separate area in memory. The first line
reserves space for the variable a and puts the value of the integer 1
in that memory space. The second line reserves space for the variable
b and then copies the value from a's memory space into b's memory
space.

In the following Ruby code:

  a = 1
  b = a

the first line reserves memory space (behind the scenes in the code
for the Ruby interpreter) for an instance of Fixnum and creates a new
instance of Fixnum with the value of 1. It then assigns a reference to
that instance of Fixnum to the variable a. However, the second line
does not create a new Fixnum address space in memory. The second line
simply tells the variable b to reference the same object that variable
a currently references. This is similar to (but not exactly the same
as) the following C code:

  int x = 1; /* this (sort of) happens behind the scenes in Ruby */
  int a = &x;
  int b = a;

The difference is that, since Ruby doesn't have explicit pointers, any
methods invoked on the a or b variables are automatically dereferenced
and called on the actual Fixnum object those variable point to (I
guess you could say the "pointer" is both implicit _and_ unavoidable).
In C, you would have to specifically dereference the variable,
otherwise you would be operating on the memory address instead of the
_contents_ of that memory space.

In C, whenever you use the assignment operator, you are basically
saying "replace the contents of the memory pointed to by the lhs with
the _value_ on the rhs. In contrast, when you use the assignment
operator in Ruby, you are saying "replace the reference to the object
(essentially a memory space) being pointed to by the lhs with a
reference to the object (again, essentially a memory space) being
pointed to by the rhs".

Does that make any kind of sense? (Perhaps it's devolved to rambling
at this point.)

--
Regards,
John Wilger
http://johnwilger.com

-----------
Alice came to a fork in the road. "Which road do I take?" she asked.
"Where do you want to go?" responded the Cheshire cat.
"I don't know," Alice answered.
"Then," said the cat, "it doesn't matter."
- Lewis Carrol, Alice in Wonderland
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 ara.t.howard (Guest)
on 2005-12-06 17:08
(Received via mailing list)
On Tue, 6 Dec 2005, Peter Fitzgibbons wrote:

> [Onur] It may be educational to be checking Object#id in the above examples
> (add a bunch of puts to the code).
>
> [John] Try these defs on for size :
> With pointers, we can pass the values 'by reference.' Passing by reference
> means that we'll pass the *addresses* of the variables instead of the
> values. pass-by-value vs.
> 
pass-by-reference<http://www.cs.princeton.edu/%7Elworthin/126/precep...

does this function pass by value or reference?

   void foo (void *object);

well - both in a sense.  it takes a reference and that reference is
passed by
value.  this is how ruby works because all variables are already
pointers - in
one sense they are passed by value since a copy of the address is placed
on
the stack and in another sense they are passed by reference since only
object
addresses, and never there values, are placed on the stack.  in short,
the
distinction between pass-by-value and pass-by-reference loses some
meaning in
a language with variables of only one type : reference.

regards.

-a
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 ara.t.howard (Guest)
on 2005-12-06 17:16
(Received via mailing list)
On Tue, 6 Dec 2005, John Wilger wrote:

> OK, I'm far from an expert on C, and this is based on my
> understanding; so if anyone notices any glaring errors, please correct
> me.
>
> In C, when you have "int a = 1;", the value of a is 1 (a primitive
> type). In Ruby, when you have "a = 1", the value of a is actually a
> reference to an instance of Fixnum which represents the integer 1.
> Ruby _has_no_primitive_types_ (ok, it's implimented in C, so they do
> exist behind the scenes; but there is no way to access a pure
> primitive type within your Ruby code).

ints in ruby are not boxed.  when you say

   a = 1

a has 31 bits which __are__ 1 and 1 bit that marks the word as __not__
being a
reference but an immeadiate value.

ints are, in fact, primitive types.   the only reason you can say
-42.abs is
that ruby stores all the methods of Fixnum is a special place that is
shared
by all ints.  that is why you can do this

     harp:~ > cat a.rb
     a = []

     class << a
       def foo
         42
       end
     end

     p a.foo


     harp:~ > ruby a.rb
     42


but not this


     harp:~ > cat a.rb
     a = 42

     class << a
       def foo
         42
       end
     end

     p a.foo


     harp:~ > ruby a.rb
     a.rb:3: no singleton class for Fixnum (TypeError)


regards.

-a
--
===============================================================================
| ara [dot] t [dot] howard [at] noaa [dot] gov
| all happiness comes from the desire for others to be happy.  all misery
| comes from the desire for oneself to be happy.
| -- bodhicaryavatara
===============================================================================
10d9ed7ab11115b081bb36f56a7a13bc?d=identicon&s=25 johnwilger (Guest)
on 2005-12-06 19:07
(Received via mailing list)
On 12/6/05, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:
> On Tue, 6 Dec 2005, John Wilger wrote:
> > Ruby _has_no_primitive_types_ (ok, it's implimented in C, so they do
> > exist behind the scenes; but there is no way to access a pure
> > primitive type within your Ruby code).
>
> ints are, in fact, primitive types.   the only reason you can say -42.abs is
> that ruby stores all the methods of Fixnum is a special place that is shared
> by all ints.

You are, of course, correct. I probably should have used strings in
those examples (I think the practical effect is the same either way,
but I admit that my example was technically incorrect).

I hadn't realized that about Fixnum -- I think what threw me off was
the fact that you would get the same value for #object_id. On further
investigation, it would seem that integers _always_ have the same
object_id for a given value.

  a = 1
  b = a

  a.object_id    #=> 3
  b.object_id    #=> 3

  a = 1
  b = 1

  a.object_id    #=> 3
  b.object_id    #=> 3

  1.object_id    #=> 3

So let's say I do

  a = 1
  b = 1
  c = 1
  d = 1

Does Ruby store 4 different copies of 1 in memory (128 bits of memory
used), or does it only store 1 copy and cause all 4 variables to
reference that copy (32 bits of memory used). Since 1 can _never_ be
anything except 1, I would think that many programs would see a
significant improvement in memory usage if specific integers were only
stored once in memory, but perhaps that would cause a decrease in
execution speed (I have no idea)?

--
Regards,
John Wilger
http://johnwilger.com

-----------
Alice came to a fork in the road. "Which road do I take?" she asked.
"Where do you want to go?" responded the Cheshire cat.
"I don't know," Alice answered.
"Then," said the cat, "it doesn't matter."
- Lewis Carrol, Alice in Wonderland
Cb48ca5059faf7409a5ab3745a964696?d=identicon&s=25 ara.t.howard (Guest)
on 2005-12-06 19:27
(Received via mailing list)
On Tue, 6 Dec 2005, John Wilger wrote:

> You are, of course, correct. I probably should have used strings in
> those examples (I think the practical effect is the same either way,
> but I admit that my example was technically incorrect).

i thought that might have been the case ;-)

>
>  a = 1
>  b = 1
>  c = 1
>  d = 1
>
> Does Ruby store 4 different copies of 1 in memory (128 bits of memory used),
> or does it only store 1 copy and cause all 4 variables to reference that
> copy (32 bits of memory used).

but a reference is, itself, 32 bits ;-) so storing 4 references to 1
would
require 128 bits of memory __plus__ 32 for the actual '1'.

> Since 1 can _never_ be anything except 1, I would think that many programs
> would see a significant improvement in memory usage if specific integers
> were only stored once in memory, but perhaps that would cause a decrease in
> execution speed (I have no idea)?

so, since storing the address of 1 takes the same space as storing 1 (4
bytes
on most platforms) there really can't be any savings in space.  but
storing 1
directly (un-boxed ints) defintely gives an execution speed boost.

regards.

-a
--
===============================================================================
| ara [dot] t [dot] howard [at] noaa [dot] gov
| all happiness comes from the desire for others to be happy.  all misery
| comes from the desire for oneself to be happy.
| -- bodhicaryavatara
===============================================================================
3ccecc71b9fb0a3d7f00a0bef6f0a63a?d=identicon&s=25 ksruby (Guest)
on 2005-12-06 20:28
(Received via mailing list)
Ara,

There's a strong confusion of what exactly pass-by-reference means. I
always
thought that if a language supports pass-by-reference semantics, then
when
you define a method, one or several parameters can be declared as OUT
parameters.

For example,

[this is a pseudo-code]

def amethod( ref a )
  a = "two"
end

a = "one"
amethod(a)

p a # => "two"

Here I'm not using String#replace method. Otherwise the initial object
"one"
stays the same but the content of the object changes which isn't
pass-by-reference goal.

Kent.
01d7a451018ac15518f425078ef00c40?d=identicon&s=25 sitharus-rails (Guest)
on 2005-12-06 21:21
(Received via mailing list)
On 7/12/2005, at 8:24 AM, Kent Sibilev wrote:

> There's a strong confusion of what exactly pass-by-reference means.
> I always
> thought that if a language supports pass-by-reference semantics,
> then when
> you define a method, one or several parameters can be declared as OUT
> parameters.

That's a completely different thing all together, and not needed in
Ruby, I'll explain below.

The difference is simple if you understand pointers and C function
calls. Pass by value means that the actual value - the number - gets
copied in to a new memory space for the function, in pseudocode:

int i = 1; // Memory address 'i' contains the value 1
int r = add_one(i); // Go to function add_one, value 1 is sent,
memory address r is then set to 2
int add_one(int q) { // Memory address 'q' now contains 1
   return q+1; // After this memory address 'return' for want of a
better description contains 2
}
So i and r are completely separate, change either one and the other
won't be affected.

This is pass by reference, again in c-ish pseudocode. The memory
address is passed around so the value itself never gets copied.

int* i = 1; // Memory space 'i' contains the address of a memory
address that contains 1;
add_one(i); // Go to function add_one, the value passed is the memory
address.
void add_one(int* q) { // Memory address q contains the memory
address from i, this is copied.
	*q = *q + 1; // The memory address referenced by q is now set to 2.
This memory address is also referenced by i, so *i is now 2.
}
In this case only one value is used - *i - but references to it are
passed around. All OO languages work like this, but not all objects
can be modified. Here's another pseudocode example, in Ruby-ish.

i = 1 # i is a reference to an object that behaves like the integer
'1'. Wordy huh?
add_one(i) # Passes the reference to i in to add_one
def add_one(r) # r is a reference to the same object referenced by i
   r = r + 1 # Integers are immutable, so r is now a pointer to a NEW
object representing '2'. r has changed
end

If i was to change when r does then i would have to be a reference to
a reference, and that reminds me of the OS 9 memory manager... Also,
if Ruby was pass-by-value then r would contain a brand new object,
and that reminds me of PHP4, not good.

Pass by reference to return values is only useful for languages
without a native array type and parallel assignment. If you think
it'll boost speed then you're thinking on the wrong tracks, you
should look to other areas first, and do a quick search for
'premature optimisation'.

Here's a Ruby example of something that has to return two results.
Anything could be returned, they're all just objects.

def crazy_add(q, r, s)
   [q+s, r+s]
end

i, j, k = 2, 3, 4 # i = 2, j = 3, k = 4. Remember the construct.
a, b = crazy_add(i, j, k) # a = 6, b = 7

The key point people seem to be missing is that integers in Ruby are
immutable objects - they can never be changed, but if strings or some
other object was used then modifying in place is easily possible. I
know there are some differences between a normal object and an
Integer for speed reasons, but just think of them as any other
object. In Python strings are also immutable, so a similar issue
could be found.

I hope this does something to clarify the issue.

--
Phillip Hutchings
phillip.hutchings@sitharus.com
3ccecc71b9fb0a3d7f00a0bef6f0a63a?d=identicon&s=25 ksruby (Guest)
on 2005-12-06 23:32
(Received via mailing list)
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.
http://www.jguru.com/faq/view.jsp?EID=430996

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

Cheers,
Kent.
3203ed0e608d3bfae1e31282e629ffa2?d=identicon&s=25 peter.fitzgibbons (Guest)
on 2005-12-06 23:44
(Received via mailing list)
On 12/6/05, Peter Fitzgibbons <peter.fitzgibbons@gmail.com> wrote:
> >
> > Rails@lists.rubyonrails.org
>
> --
> ------------------------------
> Joyeux Noël
> ------------------------------
> Peter Fitzgibbons
>

I want to try my definition on again.  My point to posting it was to
clarify
the difference between the "value" of a primitive and the "address" of a
pointer-referenced object.

Ruby's Object and all descendants (not Fixnum) are pointer-referenced
objects.  Ruby's treatment of Fixnum sounds to be (bluntly, (grossly?))
a
cached-processing algorithm for Fixnum... the same reference process is
used
for Object+Fixnum and an if..then on the high-bit tells the process path
to
use the Fixnum cached-instance on the value of the pointer(31-bits).

A. does this explanation jive?
B. I agree with the above posts... this sub-thread has nothing to do
with
wether ruby supports "pass-by-reference" (it does not).
C. I won't bother you any more with my sub-guru antics.

--
01d7a451018ac15518f425078ef00c40?d=identicon&s=25 sitharus-rails (Guest)
on 2005-12-07 00:17
(Received via mailing list)
On 7/12/2005, at 11:32 AM, Kent Sibilev 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 Hutchings
phillip.hutchings@sitharus.com
6828ffc79486cd2442714bf32286a910?d=identicon&s=25 krishna.vivek (Guest)
on 2005-12-07 13:47
(Received via mailing list)
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
A43430351a6d4fb6d61d000bd56ed19a?d=identicon&s=25 francois (Guest)
on 2005-12-07 14:11
(Received via mailing list)
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
01d7a451018ac15518f425078ef00c40?d=identicon&s=25 sitharus-rails (Guest)
on 2005-12-07 19:21
(Received via mailing list)
On 8/12/2005, at 1:46 AM, Vivek Krishna 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 Hutchings
phillip.hutchings@sitharus.com
Eea7ad39737b0dbf3de38874e0a6c7d8?d=identicon&s=25 justin (Guest)
on 2005-12-08 00:17
(Received via mailing list)
Phillip Hutchings wrote:
>   i += 1
^^^^^^  didn't you mean:  i + 1  ?
                               =====
01d7a451018ac15518f425078ef00c40?d=identicon&s=25 sitharus-rails (Guest)
on 2005-12-08 00:22
(Received via mailing list)
On 8/12/2005, at 12:13 PM, Justin Forder 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 ;)


--
Phillip Hutchings
phillip.hutchings@sitharus.com
6828ffc79486cd2442714bf32286a910?d=identicon&s=25 krishna.vivek (Guest)
on 2005-12-08 04:33
(Received via mailing list)
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?
01d7a451018ac15518f425078ef00c40?d=identicon&s=25 sitharus-rails (Guest)
on 2005-12-08 04:41
(Received via mailing list)
On 8/12/2005, at 4:31 PM, Vivek Krishna 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 Hutchings
phillip.hutchings@sitharus.com
E146c40bd510d1f1e455723485159670?d=identicon&s=25 zorander (Guest)
on 2005-12-08 22:14
(Received via mailing list)
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 Hutchings <sitharus-rails@sitharus.com> wrote:
> def check_status
>
> _______________________________________________
> Rails mailing list
> Rails@lists.rubyonrails.org
> 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
bluczkie@andrew.cmu.edu, don't be concerned This is my new address,
but mail will be forwarded here indefinitely)
A2b2f4ee23989dc68529baef9cbddcd6?d=identicon&s=25 Julian 'Julik' Tarkhanov (Guest)
on 2005-12-13 15:13
(Received via mailing list)
On 7-dec-2005, at 13:46, Vivek Krishna 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
58e477c4841278faddacdd3bf1c8a188?d=identicon&s=25 Kazuyoshi Tlacaelel (kazuyoshi__tlacaelel)
on 2008-04-08 15:23
I got it, I go it, I got it!!!!!!!!


def change str
    str.replace '...'
end

str = '.'
change str
puts str

#=> ...

# yey!
58e477c4841278faddacdd3bf1c8a188?d=identicon&s=25 Kazuyoshi Tlacaelel (kazuyoshi__tlacaelel)
on 2008-04-08 15:27
this should be inherited from kernel/Object and then overriden
so a clear interface can be followed, my personal belief.
9de990c098cf1277d9ffe48f42011ef8?d=identicon&s=25 Doug Glidden (carluva)
on 2008-09-08 15:29
Kazuyoshi Tlacaelel 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 = 'me@home.com'
  => "me@home.com"
  irb> p
  => #<Person:0x2bc43d0 @personal_email="me@home.com",
@field_list=[:first_name, :last_name, :middle_name, :location,
:primary_email, :primary_phone_number, :personal_email]>
  irb> p.primary_email = p.personal_email
  => "me@home.com"
  irb> p
  => #<Person:0x2bc43d0 @personal_email="me@home.com",
@primary_email="me@home.com", @field_list=[:first_name, :last_name,
:middle_name, :location, :primary_email, :primary_phone_number,
:personal_email]>
  irb> p.personal_email.replace 'me@gmail.com'
  => "me@gmail.com"
  irb> p
  => #<Person:0x2bc43d0 @personal_email="me@gmail.com",
@primary_email="me@gmail.com", @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 'me@gmail.com'" can be replaced with
"p.personal_email = 'me@gmail.com'" 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
2970b59b3c126efa578993e66c9bcfab?d=identicon&s=25 Zachary Smith (zachary_s)
on 2015-01-10 11:06
>>  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'
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.