Closures 101

class Object
def singleton_class
class << self
self
end
end
end

data = Object.new
status = “good”
data.singleton_class.class_eval {
define_method(:status) {
status
}
}
p data.status # => “good”
status = “bad”
p data.status # => “bad”

I have a decent amount of experience with ruby, but I have somehow
misunderstood closures this whole time. I thought a closure contained
a full “snapshot” of the stack, but actually it contains references to
the stack. That is, I thought <<status = “bad”>> would have no
effect.

This came about from the following situation:

def add_status(array)
index = 0
while index < array.size
status = “running #{index}”
array[index].singleton_class.class_eval {
define_method(:status) {
status
}
}
index += 1
end
end

array = %w(a b c)
add_status(array)
array.each { |elem| p elem.status }

=> “running 2”

=> “running 2”

=> “running 2”

If we replace “while index < array.size” with “array.size.times do”
then we get

=> “running 0”

=> “running 1”

=> “running 2”

So “times” uses a closure which in turn creates a new “status”
variable, whereas the while loop does not use a closure and there is
only one “status”.

I haven’t encountered this behavior before since I rarely use such
uncouth imperative-style iterations. I’m not sure I have a point, per
se, except that it’s possible to use ruby for a long time without
fully understanding closures.

Hi –

On Fri, 14 Mar 2008, [email protected] wrote:

data.singleton_class.class_eval {
a full “snapshot” of the stack, but actually it contains references to
the stack. That is, I thought <<status = “bad”>> would have no
effect.

I think it’s best to think of the closure as preserving a binding. In
that binding, the identifier “status” is bound to “bad”. If you
reassign to status, you’re changing the binding of status inside the
(overall) binding. The closure continues to reflect that binding.

David

update your blog!

-------------------------------------------------------|
~ Ari
Some people want love
Others want money
Me… Well…
I just want this code to compile

Jeff

David explained it very properly. Maybe you might be interested to
read more about it on my blog.
I have written some code that allows to replace ivars with closures
(idea stolen from Tom Christiansen’s famous Tom’s Object Tutorial in
perl).
This is much slower (about 5 to 10 !!) but might be of interest for
thrade safety and the complete encapsulation (this was Tom’s
motivation in the famous TOT)
Anyway it is quite some read —> http://ruby-smalltalk.blogspot.com/

Cheers
Robert

Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

On Fri, Mar 14, 2008 at 8:45 PM, fedzor [email protected] wrote:

update your blog!
???
What’s wrong?

-------------------------------------------------------|
~ Ari
Some people want love
Others want money
Me… Well…
I just want this code to compile


http://ruby-smalltalk.blogspot.com/


Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

i would guess that they were saying:

good stuff on there.
just not much and nothing recent.

take it as an encore! encore!

On Sat, Mar 15, 2008 at 4:21 PM, Sean A. [email protected]
wrote:

i would guess that they were saying:

good stuff on there.
just not much and nothing recent.

take it as an encore! encore!

That’s very kind of you, but my head is empty and my schedule is full
right now … :frowning:
Cheers
Robert

http://ruby-smalltalk.blogspot.com/


Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein