How to pass arguments by reference in a function

Discussion in 'Ruby' started by ashishwave, Jul 27, 2007.

  1. ashishwave

    ashishwave Guest

    if i pass arguments in a function then they get passed by value. how
    to get it pased by reference.
    For example: if i want to swrite my own swap function (not using
    multiple assignment syntax a,b=b,a) just for example example, how to
    implement that in ruby

    bye :)
    Ashish Ranjan
     
    ashishwave, Jul 27, 2007
    #1
    1. Advertising

  2. 2007/7/27, ashishwave <>:
    > if i pass arguments in a function then they get passed by value. how
    > to get it passed by reference.


    You can't. There are some solutions to this depending on situation:

    1. inplace modification of arguments (Strings, Arrays, Hashes - all
    sorts of containers)

    2. multiple return values

    3. work with instance variables

    Generally in my experience it's not needed.

    > For example: if i want to swrite my own swap function (not using
    > multiple assignment syntax a,b=b,a) just for example example, how to
    > implement that in ruby


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

    But in reality you would just do

    x,y = y,x

    Kind regards

    robert
     
    Robert Klemme, Jul 27, 2007
    #2
    1. Advertising

  3. ashishwave

    Phlip Guest

    ashishwave wrote:

    > if i pass arguments in a function then they get passed by value.


    Ruby supports two kinds of variables; IIRC numbers, characters, booleans,
    and nil are "immediate", and everything else is a reference to an object.

    The best way to explain this is to look at Ruby's source. A VALUE is the
    union of a long and a pointer. Anything small enough to fit in a long is an
    immediate value, and everything else uses the pointer to point to a
    non-immediate object.

    So at function call time, Ruby passes the _VALUE_ by value. So immediates
    get copied, and objects get passed by reference.

    So, in addition to your other answer, you could also put your referend into
    a class, and pass this around. That might fit the ideals of Object Oriented
    Programming better than passing immediates would.

    --
    Phlip
    http://www.oreilly.com/catalog/9780596510657/
    ^ assert_xpath
    http://tinyurl.com/23tlu5 <-- assert_raise_message
     
    Phlip, Jul 27, 2007
    #3
  4. ashishwave

    Phlip Guest

    Robert Klemme wrote:

    > I think "pass by reference" is not the proper term because that would
    > imply that you could change a variable in the calling scope, i.e. you
    > could do
    >
    > def magic(x) x = 10 end
    > foo = 1
    > puts foo # prints 1
    > magic(foo)
    > puts foo # prints 10
    >
    > which you can't.


    Working backwards from your example, that is the definition of an "immediate
    value". Violent agreement achieved!

    --
    Phlip
    http://www.oreilly.com/catalog/9780596510657/
    ^ assert_xpath
    http://tinyurl.com/23tlu5 <-- assert_raise_message
     
    Phlip, Jul 27, 2007
    #4
  5. 2007/7/27, Phlip <>:
    > ashishwave wrote:
    >
    > > if i pass arguments in a function then they get passed by value.

    >
    > Ruby supports two kinds of variables; IIRC numbers, characters, booleans,
    > and nil are "immediate", and everything else is a reference to an object.


    Personally I find it easier to grasp (especially when starting out
    with Ruby) this when you assume that everything is an object.
    Although there are some optimizations going on behind the scenes all
    objects behave the same - from a Ruby user's perspective. This is
    totally different from Java's handling of PODs for example.

    > The best way to explain this is to look at Ruby's source. A VALUE is the
    > union of a long and a pointer. Anything small enough to fit in a long is an
    > immediate value, and everything else uses the pointer to point to a
    > non-immediate object.


    Again, I would not start with Ruby sources here.

    > So at function call time, Ruby passes the _VALUE_ by value. So immediates
    > get copied, and objects get passed by reference.


    I think "pass by reference" is not the proper term because that would
    imply that you could change a variable in the calling scope, i.e. you
    could do

    def magic(x) x = 10 end
    foo = 1
    puts foo # prints 1
    magic(foo)
    puts foo # prints 10

    which you can't. I'd rather call it "call by reference value", i.e.
    the reference is copied.

    > So, in addition to your other answer, you could also put your referend into
    > a class, and pass this around. That might fit the ideals of Object Oriented
    > Programming better than passing immediates would.


    I am not sure why you refer to immediates here. Using instance
    variables is generally one of the core OO techniques.

    Kind regards

    robert
     
    Robert Klemme, Jul 27, 2007
    #5
  6. On Jul 27, 8:32 am, "Robert Klemme" <>
    wrote:
    > 2007/7/27, ashishwave <>:
    >
    > > if i pass arguments in a function then they get passed by value. how
    > > to get it passed by reference.

    >
    > You can't. There are some solutions to this depending on situation:
    >
    > 1. inplace modification of arguments (Strings, Arrays, Hashes - all
    > sorts of containers)
    >
    > 2. multiple return values
    >
    > 3. work with instance variables


    4. passing lambdas around

    x, y = 1, 2
    x_ref = [lambda { x }, lambda { |x| }]
    y_ref = [lambda { y }, lambda { |y| }]
    swap(x_ref, y_ref}

    See http://flgr.0x42.net/code/variable.rb
     
    Florian Gross, Jul 27, 2007
    #6
  7. ashishwave wrote:
    > For example: if i want to write my own swap function (not using
    > multiple assignment syntax a,b=b,a) just for example example, how to
    > implement that in ruby


    That reminds me, in the old days you could do a swap without a third
    variable using XOR. e.g.

    a = 13
    b = 17

    a ^= b
    b ^= a
    a ^= b

    and they are swapped.

    I know that Ruby might do it as mentioned above.

    My question is, which is more efficient?
    --
    Posted via http://www.ruby-forum.com/.
     
    Lloyd Linklater, Jul 27, 2007
    #7
  8. ashishwave

    Ian Whitlock Guest

    Lloyd Linklater wrote:
    > My question is, which is more efficient?


    It may depends on the definition of efficient.
    Try it with a = "13" and b = "17".

    In terms of execution time it is a horse race
    that doesn't matter much. Try

    require "benchmark"
    include Benchmark

    n = 100001

    bm(10) do |x|
    a = 13
    b = 17
    x.report("XOR") {n.times {a ^= b;b ^= a;a ^= b} }
    puts a , b
    x.report("ruby") {n.times {b,a = a,b} }
    puts a , b
    end

    Ian
    --
    Posted via http://www.ruby-forum.com/.
     
    Ian Whitlock, Jul 27, 2007
    #8
  9. On 27.07.2007 11:22, Phlip wrote:
    > Robert Klemme wrote:
    >
    >> I think "pass by reference" is not the proper term because that would
    >> imply that you could change a variable in the calling scope, i.e. you
    >> could do
    >>
    >> def magic(x) x = 10 end
    >> foo = 1
    >> puts foo # prints 1
    >> magic(foo)
    >> puts foo # prints 10
    >>
    >> which you can't.

    >
    > Working backwards from your example, that is the definition of an "immediate
    > value". Violent agreement achieved!


    I'm not sure where you see the agreement and also I don't see how the
    piece above makes for a definition of an immediate value. Did I miss a
    smiley somewhere?

    An immediate value is something that does not live on the heap but where
    the reference is the value. Other than that it behaves the same as any
    other object. Immediate values are just an interpreter internal
    optimization - you wouldn't notice if that was abandoned and Fixnums
    became ordinary instances like others (apart from performance of course).

    The example presented by me does not work - regardless whether you use a
    Fixnum, an Array or some other object. This has only to do with the
    parameter passing mode.

    Kind regards

    robert
     
    Robert Klemme, Jul 27, 2007
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jerry
    Replies:
    20
    Views:
    8,039
    Roedy Green
    Sep 9, 2005
  2. blufox
    Replies:
    2
    Views:
    593
  3. Mr A
    Replies:
    111
    Views:
    2,181
  4. Robert
    Replies:
    10
    Views:
    1,395
    E. Robert Tisdale
    Aug 24, 2005
  5. jmborr
    Replies:
    1
    Views:
    454
    Stargaming
    Nov 3, 2007
Loading...

Share This Page