Arguments and formal variables

In first place I sorprised with te behavior of formal variables inside a
metod or proc:

irb(main):020:0> a=proc { |i| p i.id;i=7;p i.id}
=> #Proc:0x4028b604@:20(irb)
irb(main):021:0> b=5
=> 5
irb(main):022:0> b.id
=> 11
irb(main):023:0> a.call(b)
11
15
=> nil
irb(main):024:0> b.id
=> 11

I google this and in the faq warn about it, calling it formal variables.

Ok, if I want to change the value of a Array i can use Array#replace,
but is a way to change other types, Fixnum for example.
Is any way to do this??

Thanks in advance,
Angel

Angel Martin wrote:

In first place I sorprised with te behavior of formal variables inside a
metod or proc:

irb(main):020:0> a=proc { |i| p i.id;i=7;p i.id}
=> #Proc:0x4028b604@:20(irb)
irb(main):021:0> b=5
=> 5
irb(main):022:0> b.id
=> 11
irb(main):023:0> a.call(b)
11
15
=> nil
irb(main):024:0> b.id
=> 11

I google this and in the faq warn about it, calling it formal variables.

Ok, if I want to change the value of a Array i can use Array#replace,
but is a way to change other types, Fixnum for example.
Is any way to do this??

You will need to box the value… there are many way to do this,
The most common quick and dirty solution is to use an Array,
but you can also do:

class Boxer
def initialize(ref)
@ref = ref
end
attr_reader :ref
def set(ref)
@ref = ref
end
end
a=proc { |i|
p i.ref.object_id # → 11
i.set(7)
p i.ref.object_id # → 15
}
b=Boxer.new(5)
p b.ref.object_id # → 11
a.call(b)
p b.ref.object_id # → 15

···


Simon Strandgaard

“Angel Martin” angel@tyrex.mine.nu schrieb im Newsbeitrag
news:1084970490.26805.37.camel@tyrex.mine.nu…

In first place I sorprised with te behavior of formal variables inside a
metod or proc:

Why are you surprised? Formal method / proc parameters and bound to some
ruby instances on method invocation. Whenever you assign to them from
inside the method / proc, only this variable binding changes. These
variables are not aliases for any other variables. If they would be, you
could not do this, because initialization is done from an expression
evaluation and not a variable:

def bar(x)
puts x
x = 100
puts x
end

bar( 5 + 10 )

Regards

robert

“Angel Martin” angel@tyrex.mine.nu schrieb im Newsbeitrag
news:1084970490.26805.37.camel@tyrex.mine.nu…

In first place I sorprised with te behavior of formal variables inside a
metod or proc:

Why are you surprised? Formal method / proc parameters and bound to some
ruby instances on method invocation. Whenever you assign to them from
inside the method / proc, only this variable binding changes. These
variables are not aliases for any other variables.

Because a C pointer view :slight_smile:

It seems to me that the arguments in method are new instances of the
container, I mean:
‘a’ outside is a pointer(in C) to the struct that hold the container of
ref to obj
‘a’ arguments is a pointer to a new struct which contains the same ref,

If assign (=) change the ruby ref of the container, but in the new scope
‘a’ is now a container.dup, I can’t change the ref outside :frowning:

The sentence “In Ruby all object are passed be reference” give me a
‘pointer view’ of this.

The Array wraping values IHMO seems to be a little Ugly, but simple
enought to me.

If they would be, you
could not do this, because initialization is done from an expression
evaluation and not a variable:
Please, can you explain a litle more about?
What is the difference in initialization between a expresion evaluation
and a variable if expresion return some type of value.

Thanks,
Angel

···

El mié, 19-05-2004 a las 16:38, Robert Klemme escribió:

“Angel Martin” angel@tyrex.mine.nu schrieb im Newsbeitrag
news:1084980569.26803.69.camel@tyrex.mine.nu…

“Angel Martin” angel@tyrex.mine.nu schrieb im Newsbeitrag
news:1084970490.26805.37.camel@tyrex.mine.nu…

In first place I sorprised with te behavior of formal variables inside
a
metod or proc:

Why are you surprised? Formal method / proc parameters and bound to
some
ruby instances on method invocation. Whenever you assign to them from
inside the method / proc, only this variable binding changes. These
variables are not aliases for any other variables.

Because a C pointer view :slight_smile:

It seems to me that the arguments in method are new instances of the
container, I mean:
‘a’ outside is a pointer(in C) to the struct that hold the container of
ref to obj
‘a’ arguments is a pointer to a new struct which contains the same ref,

If assign (=) change the ruby ref of the container, but in the new scope
‘a’ is now a container.dup, I can’t change the ref outside :frowning:

If you replace “contianer” by “reference” then you get it right IMHO.

The sentence “In Ruby all object are passed be reference” give me a
‘pointer view’ of this.

The Array wraping values IHMO seems to be a little Ugly, but simple
enought to me.

Personally I’ve never felt the need in a method to change a binding in the
calling context. Why do you think you need that?

If they would be, you
could not do this, because initialization is done from an expression
evaluation and not a variable:
Please, can you explain a litle more about?
What is the difference in initialization between a expresion evaluation
and a variable if expresion return some type of value.

An expression is not an lvalue (something you can assign to). There’s no
place (like a variable), just a value (in Ruby: an object).

Regards

robert
···

El mié, 19-05-2004 a las 16:38, Robert Klemme escribió: