Forum: Ruby How to use a passing argument(returned argument)?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
김 준영 (Guest)
on 2008-11-26 03:55
(Received via mailing list)
Hello, everyone !!!

I have question about how to use a passing argument. firstly let me
show sample code.

a = 0

def set10(aArg)
  aArg = 10
end

set10(a)

p a <--- I wanna get 10 as a result.


How can I do for this one?
Eric I. (Guest)
on 2008-11-26 05:30
(Received via mailing list)
On Nov 25, 8:49 pm, ±è ÁØ¿µ <removed_email_address@domain.invalid> wrote:
>
> set10(a)
>
> p a <--- I wanna get 10 as a result.
>
> How can I do for this one?

Well, Ruby, being a purely object-oriented language, means that
assigning a value to a variable assigns it to a new object (instance)
without affecting the original.  So in your example, you just make the
parameter aArg refer to a new number leaving the original untouched.

To alter the data in a parameter, you would have to call a method on
the parameter that changes the data.  For example:

----

def method1(string)
  string.upcase!
end

s = "hello"
method1(s)
p s  # displays "HELLO"

----

Now, some classes have immutable instances -- instances that cannot
have the data within them altered.  Fixnum, Bignum, and Float (the
basic numeric types) are all immutable.  So that presents a problem.

What you could do is wrap the immutable instance in a mutable class,
as in:

----

require 'delegate'

class Mutable < SimpleDelegator
  def initialize(value)
    @value = value
    super(@value)
  end

  def reassign(new_value)
    @value = new_value
    __setobj__(@value)
  end
end

def method2(number)
  number.reassign(10)
end

n = Mutable.new(3)
method2(n)
p n  # displays 10

n = Mutable.new("test")
p n  # displays "test"
method2(n)
p n  # displays 10

----

I hope that's helpful.

Eric

====

Are you interested in on-site Ruby or Ruby on Rails training
that uses well-designed, real-world, hands-on exercises?
http://LearnRuby.com
Joshua B. (Guest)
on 2008-11-26 06:24
(Received via mailing list)
On Nov 25, 2008, at 8:49 PM, 김 준영 wrote:

> Hello, everyone !!!

Hi there!

>
> p a <--- I wanna get 10 as a result.
>
>
> How can I do for this one?

First, the pattern you are looking for is not very object oriented-y.
That is, you're asking to remove some of the logic pertaining to 'a'
and put it somewhere outside of 'a'. Since 'a' is an object
(everything in Ruby is), then it would be best if you made 'a' an
instance of a class with the 'set10' logic in it. The sort of pass-by-
reference pattern you're looking for is much more typical of C.

That said, this would be, I think, the closest equivalent in Ruby:

a = 0

def set10(aArg_name,  bind)
   eval("#{aArg_name} = 10", bind)
end

set10('a', binding)

p a

=> 10

Cheers,

Josh
Einar Magnús Boson (Guest)
on 2008-11-26 06:43
(Received via mailing list)
On 26.11.2008, at 04:19 , Joshua B. wrote:

>>
>
>
> Cheers,
>
> Josh
>
>


I did not know this, google filled me in and this might be relevant to
the original question:
http://onestepback.org/index.cgi/Tech/Ruby/RubyBin...

They end up with this:

   def swap(aref, bref)
   aref.value, bref.value = bref.value, aref.value
   end

   a = 22
   b = 33
   swap(ref{:a}, ref{:b})
   p a                       # => 33
   p b                       # => 22

Pretty neat, if that's something you wanna do. Makes me wonder though:
when I first saw this (5 minutes ago) I thought you might be able to do

a = 0

def set10(aArg_name,  bind=binding)
eval("#{aArg_name} = 10", bind)
end

set10('a')

p a


but that doesn't work, in what context and when are default-values
evaluated? my guess is that they get the same closure as the method
body and are evaluated on call, is that correct?

einarmagnus
Junyoung Kim (Guest)
on 2008-11-26 06:58
(Received via mailing list)
Einar's suggestion is very good and clear everything for me :)

finally, my code should be changed like -->

   class Reference
       def initialize(var_name, vars)
           @getter = eval "lambda { #{var_name} }", vars
           @setter = eval "lambda { |v| #{var_name} = v }", vars
       end
       def value
           @getter.call
       end
       def value=(new_value)
           @setter.call(new_value)
       end
   end

   def ref(&block)
       Reference.new(block.call, block.binding)
   end

   def set10(var_a)
       var_a.value = 10
   end

   a = 22
   set10 (ref{:a})
   p a

thanks for all :)

2008. 11. 26, 오후 1:38, Einar Magnús Boson 작성:
Ken B. (Guest)
on 2008-11-27 04:11
(Received via mailing list)
On Tue, 25 Nov 2008 23:38:02 -0500, Einar Magnús Boson wrote:
>    a = 22
>    b = 33
>    swap(ref{:a}, ref{:b})
>    p a                       # => 33
>    p b                       # => 22
>
> Pretty neat, if that's something you wanna do.

That rocks. Thanks for sharing. I thought that this kind of
functionality
would require syntax built into the language.

>
> p a
>
>
> but that doesn't work, in what context and when are default-values
> evaluated? my guess is that they get the same closure as the method body
> and are evaluated on call, is that correct?

Yeah. I'd love to have a Binding.of_caller or something like that, but
have had no such luck. (Ok. It's an add-on in 1.8, but I'm curious about
1.9)
Lloyd L. (Guest)
on 2008-11-27 05:11
>    a = 22
>    b = 33
>    swap(ref{:a}, ref{:b})
>    p a                       # => 33
>    p b                       # => 22


instead of swap(ref{:a}, ref{:b})

why not a, b = b, a
Einar Magnús Boson (Guest)
on 2008-11-27 05:58
(Received via mailing list)
On 27.11.2008, at 03:06 , Lloyd L. wrote:

> --
> Posted via http://www.ruby-forum.com/.
>

Because his question was about references, swap was just an example.

einarmagnus
This topic is locked and can not be replied to.