Iterators and Assigment


#1

Consider…

def fred
yield $k
puts “in fred #{$k}”
end

$k=2
fred {|o| o = 3}
puts “outside fred #{$k}”

produces:

in fred 2
outside fred 2

why is $k still 2 after the call to fred?

Thanks in advance.


#2

Godspeed wrote:

produces:

in fred 2
outside fred 2

why is $k still 2 after the call to fred?

Because Ruby does call by value where values are object references.
Same
holds for blocks and their parameters. There is no implicit aliasing
between k$ and o. When the block is invoked you get a new reference
which
initially points to the same instance as $k. Then you assign it and it
points to some other object leaving $k still pointing to the old
instance.

Kind regards

robert

#3

Thanks guys. Your responses have cleared this up. I was assumig some
sort of
substitution (of the block into the def) going on, but I realise it is
the
other way round, the parameters to yield are parameters to the block.
Makes
perfect sense now.

“Jonathan L.” removed_email_address@domain.invalid wrote in message
news:removed_email_address@domain.invalid…


#4

On Tue, 2006-02-28 at 22:38 +0900, Robert K. wrote:

puts “outside fred #{$k}”
between k$ and o. When the block is invoked you get a new reference which
initially points to the same instance as $k. Then you assign it and it
points to some other object leaving $k still pointing to the old instance.

Kind regards

robert

So, try this:

def fred
$k = yield
puts “in fred #{$k}”
end

$k = 2
fred { 3 }
puts “outside fred #{$k}”

Returns:

in fred 3
outside fred 3

You can call yield with parameters if you need the value of $k to be
accessible inside the block. Although $k is accessible inside the block
anyway as it’s a global. Although you’re probably not using a global in
your actual code.

Regards