[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: Method arguments

e

2/9/2005 6:40:00 AM

> Lähettäjä: Nash Kabbara <nash@oplink.net>
> Aihe: Re: Method arguments
>
> Hmmm. Is it safe to pass a Hash and modify it in a function then use it?
>
> for example:
>
> a = Hash.new
> modify(a)
> do_something_useful(a)
>
> after reading the response below, it's making me think how hashs behave
> and whether it's safe to do the above.

It depends on what you expect :)

def foo(hsh)
hsh[:a] = 'b'
end

h = {:a => 'a'}
foo(h)

h[:a] # => 'b'

> Thanks
>
>
> Mikael Brockman wrote:
> > "Tookelso" <tookskie-googlegroups@yahoo.com> writes:
> >
> >
> >>Hello,
> >>
> >>Sorry for asking this basic question, but I couldn't find it in the
> >>PickAxe book.
> >>
> >>When you pass an argument to a method, is it passed by reference, or by
> >>value?
> >
> >
> > By value. But remember that the value of a variable is always a
> > reference! (That's not *technically* true for Fixnums, but since
> > Fixnums are entirely immutable, the abstraction holds up.)
> >
> >
> >>Or, does it depend on the object's type?
> >>
> >>For example, in the simple script below, the program outputs "0".
> >>#-----------------------------------
> >>def test(c_count)
> >>c_count = c_count + 1
> >>end
> >># begin program
> >>c_count = 0
> >>test(c_count)
> >>puts c_count
> >>#-----------------------------------
> >>I realize that for simple things, it's better to return a value from
> >>the method, but I would like to know *why* it's not modifying my
> >>"c_count" value.
> >
> >
> > (In this explanation, I'm ignoring the fact that Fixnums are special --
> > that fact is a pure implementation detail. Just an optimization.)
> >
> > When you initialize c_count, the 0 is evaluated first. Ruby will
> > allocate space for a Fixnum. Let's say it allocates some bytes over at
> > the memory location 0xCAFEBABE. It copies 0x0000, or whatever the
> > machine representation of 0 is, to 0xCAFEBABE.
> >
> > Then it creates a new instance variable. Sets its value to 0xCAFEBABE.
> >
> > When you call ``test'', c_count is passed by value, as always. The
> > value passed is 0xCAFEBABE.
> >
> > Now, what happens when you receive an argument is this: a new instance
> > variable is created. This c_count has nothing in common with the other
> > c_count -- except that they happen to share values. Of course, you
> > could name the test parameter ``snuggly_taco'', and the program would
> > work the same.
> >
> > When you assign to snuggly_taco, the only thing that happens is that the
> > value of snuggly_taco is changed, to the address of that new number
> > you're making. This affects neither 0xCAFEBABE nor c_count.
> >
> > If you really want to change the value of an instance variable from
> > another function -- bad luck. You can't.
> >
> > Actually, I lied. You can do it. If you use Florian Groß's
> > binding_of_caller and eval.
> >
> > But that's an extremely obscure hack. Avoid it! The clean solution is,
> > as always, adding another layer of indirection. Make it so that by
> > setting something you actually can change -- like an instance variable
> > -- you change the effective value.
> >
> > | class Box
> > | attr_accessor :value
> > |
> > | def initialize value=nil
> > | @value = value
> > | end
> > | end
> > |
> > | def test c_count
> > | c_count.value = c_count.value + 1
> > | end
> > |
> > | c_count = Box.new 0
> > | test c_count
> > | puts c_count
> >
> > This box is perfectly analogous with a C pointer (except, of course,
> > that you can't do pointer arithmetic). Instead of ``*foo'', we write
> > ``foo.value''.
> >
> > (By the way, is there a class like this in the stdlib?)
> >
> > mikael
> >
> >
> >
> >

E