functions, arguments and changing their value permantently

Discussion in 'Ruby' started by Adam Akhtar, Mar 24, 2008.

  1. Adam Akhtar

    Adam Akhtar Guest

    Im coming over to Ruby from C++ after a long break from programming. One
    thing im having to get used to is how ruby references or points directly
    to variables. In C++ I can pass a variable as an argument to a function
    and then change the value within the function. This change will be
    reflected outside of the function. How do i go about doing this in ruby?

    i.e.

    x = 10

    def changeit var
    var = 20
    end

    changeit x
    puts x
    ==> 20
    --
    Posted via http://www.ruby-forum.com/.
    Adam Akhtar, Mar 24, 2008
    #1
    1. Advertising

  2. Eder Quiñones, Mar 24, 2008
    #2
    1. Advertising

  3. Adam Akhtar

    ThoML Guest

    Re: functions, arguments and changing their value permantent

    On Mar 24, 9:46 am, Eder Quiñones <> wrote:
    > x = changeit x


    You can easily return multiple arguments (x, y = changeit(x, y)) which
    makes the inout semantics rather obsolete (with a few exceptions where
    macro would be desirable). Some classes also provide destructive
    methods that can be used to replace it's contents while maintaining
    the object's identity.
    ThoML, Mar 24, 2008
    #3
  4. Adam Akhtar

    Todd Benson Guest

    On Mon, Mar 24, 2008 at 3:12 AM, Adam Akhtar <> wrote:
    > Im coming over to Ruby from C++ after a long break from programming. One
    > thing im having to get used to is how ruby references or points directly
    > to variables. In C++ I can pass a variable as an argument to a function
    > and then change the value within the function. This change will be
    > reflected outside of the function. How do i go about doing this in ruby?
    >
    > i.e.
    >
    > x = 10
    >
    > def changeit var
    > var = 20
    > end
    >
    > changeit x
    > puts x
    > ==> 20


    Ruby tries to maintain scope rigidly. So your x before will not
    change within the scope of the method changeit.

    Your method, when called, says...

    changeit 10

    Then you want to do assignment as...

    x = 20

    It's a different x!

    You can pull out of local scope with class instance variables or
    globals. Your same code, just changed...

    @x = 10

    def changeit n
    @x = n
    end

    ...or return it directly form the method if that's the only value you need

    x = 10

    def changeit n
    n
    end

    x = changeit

    ...in which case you would probably want to rename the method.

    I have to say, I don't see this as a good design pattern using Ruby,
    but I don't know what you're trying to do :)

    I can't tell by your post, but if really what you want to do is send a
    variable "name" into the method and have the method change the value.
    That's different and might require some brainiacs on the list to help
    you (my guess is that you would have use some form of #eval).

    Todd
    Todd Benson, Mar 24, 2008
    #4
  5. On Monday 24 March 2008, Adam Akhtar wrote:
    > Im coming over to Ruby from C++ after a long break from programming. One
    > thing im having to get used to is how ruby references or points directly
    > to variables. In C++ I can pass a variable as an argument to a function
    > and then change the value within the function. This change will be
    > reflected outside of the function. How do i go about doing this in ruby?
    >
    > i.e.
    >
    > x = 10
    >
    > def changeit var
    > var = 20
    > end
    >
    > changeit x
    > puts x
    > ==> 20


    In ruby you pass the object to the method, not a reference to the variable.
    This means that, if you change the object, changes will affect every variable
    which contains the object. On the other hand, changing the object contained in
    the argument of the method (that is, writing var = 20) won't affect any other
    variable. This means that if some classes are unchangeable (such as all kind
    of numbers and symbols), you can't do what you want. Other classes provide
    methods which change them in place. As I said, such changes will affect every
    variable which points to the object. Here are some examples which should make
    things clearer:

    def m1 str
    str.upcase
    end

    def m2 str
    str = "a string"
    end

    def m3 str
    str.upcase!
    end

    x = "test"

    m1 x
    puts "After m1 x is: #{x}"

    m2 x
    puts "After m2 x is: #{x}"

    m3 x
    puts "After m3 x is: #{x}"

    The output is:

    After m1 x is: test
    After m2 x is: test
    After m3 x is: TEST

    m1 calls String#upcase, which is a non-destructive method (that is, a method
    which doesn't change its receiver) and does nothing else. Of course, this
    doesn't change x.

    m2 sets the local variable str, which initially contains the argument passed
    to the method, to a different value, "a string". In C++, if the argument was a
    reference, this would have also set x to "a string". In ruby it doesn't.

    m3 calls a destructive method on str. A destructive method changes its
    receiver, so the contents of the object contained by str change (notice that
    this is different from the previous case, where a new object was put into
    str). Since str and x contain the same object, x also changes. A method like
    this can be used to achieve the result you wanted, but it can be written only
    if the argument has a destructive method which does what you need (for
    example, you couldn't have done the same for an Integer, since it doesn't have
    destructive methods).

    I hope this helps

    Stefano
    Stefano Crocco, Mar 24, 2008
    #5
  6. On 3/24/08, Adam Akhtar <> wrote:
    > Im coming over to Ruby from C++ after a long break from programming. One
    > thing im having to get used to is how ruby references or points directly
    > to variables. In C++ I can pass a variable as an argument to a function
    > and then change the value within the function. This change will be
    > reflected outside of the function. How do i go about doing this in ruby?


    Perhaps something here can help you get your head around this aspect
    of how Ruby isn't C++:

    http://talklikeaduck.denhaven2.com/articles/2006/09/13/on-variables-values-and-objects
    http://talklikeaduck.denhaven2.com/articles/2008/02/08/whose-variable-is-it-anyway
    --
    Rick DeNatale

    My blog on Ruby
    http://talklikeaduck.denhaven2.com/
    Rick DeNatale, Mar 24, 2008
    #6
  7. Adam Akhtar

    Adam Akhtar Guest

    Re: functions, arguments and changing their value permantent

    Thank you so much for all of your detailed replies. Some of you asked
    why I wanted to do this and why don`t I just return the value to the
    variable I want to change ala x = doit x

    Well actually my function changes 2 values. Functions can only pass one
    back so I thought I`d pass one as an argument as well. Is that bad
    programming design? What are other options?

    Many thanks
    --
    Posted via http://www.ruby-forum.com/.
    Adam Akhtar, Mar 24, 2008
    #7
  8. Adam Akhtar

    Adam Akhtar Guest

    Re: functions, arguments and changing their value permantent

    Sorry I missed this reply

    You can easily return multiple arguments (x, y = changeit(x, y)) which
    makes the inout semantics rather obsolete (with a few exceptions where
    macro would be desirable). Some classes also provide destructive
    methods that can be used to replace it's contents while maintaining
    the object's identity.

    which answers my question. Between reading the posts and replying I had
    a good nights sleep and still a bit groggy.



    --
    Posted via http://www.ruby-forum.com/.
    Adam Akhtar, Mar 24, 2008
    #8
  9. Adam Akhtar

    MenTaLguY Guest

    Re: functions, arguments and changing their value permantent

    On Tue, 25 Mar 2008 08:06:38 +0900, Adam Akhtar <> wrote:
    > Thank you so much for all of your detailed replies. Some of you asked
    > why I wanted to do this and why don`t I just return the value to the
    > variable I want to change ala x = doit x
    >
    > Well actually my function changes 2 values. Functions can only pass one
    > back so I thought I`d pass one as an argument as well. Is that bad
    > programming design? What are other options?


    You could have the function return multiple values as an array:

    def foo(x, y)
    [ x + y, x * y ]
    end

    sum, product = foo(2, 3)
    puts sum
    puts product

    -mental
    MenTaLguY, Mar 24, 2008
    #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. Xiangliang Meng
    Replies:
    1
    Views:
    1,581
    Victor Bazarov
    Jun 21, 2004
  2. mike p.
    Replies:
    1
    Views:
    311
    Terry Reedy
    Feb 27, 2004
  3. Martin Johansen

    Function arguments and their size

    Martin Johansen, Jun 4, 2005, in forum: C Programming
    Replies:
    5
    Views:
    381
    Lawrence Kirby
    Jun 4, 2005
  4. SamF
    Replies:
    4
    Views:
    138
    Stefano Crocco
    Mar 14, 2007
  5. oldyork90
    Replies:
    10
    Views:
    337
    Jorge
    Sep 27, 2008
Loading...

Share This Page