[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Closures 101

jeffperforce

3/14/2008 1:09:00 PM

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.

6 Answers

David A. Black

3/14/2008 1:16:00 PM

0

Hi --

On Fri, 14 Mar 2008, jeffperforce@gmail.com wrote:

> 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.

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

--
Upcoming Rails training from David A. Black and Ruby Power and Light:
ADVANCING WITH RAILS, April 14-17 2008, New York City
CORE RAILS, June 24-27 2008, London (Skills Matter)
See http://www.r... for details. Berlin dates coming soon!

Robert Dober

3/14/2008 4:11:00 PM

0

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.blo...

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

fedzor

3/14/2008 7:45:00 PM

0

update your blog!

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


Robert Dober

3/15/2008 1:15:00 AM

0

On Fri, Mar 14, 2008 at 8:45 PM, fedzor <fedzor@gmail.com> 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.blo...

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

Sean T Allen

3/15/2008 3:22:00 PM

0

i would guess that they were saying:

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

take it as an encore! encore!

On Mar 14, 2008, at 9:15 PM, Robert Dober wrote:

> On Fri, Mar 14, 2008 at 8:45 PM, fedzor <fedzor@gmail.com> 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.blo...
>
> ---
> Whereof one cannot speak, thereof one must be silent.
> Ludwig Wittgenstein
>


Robert Dober

3/15/2008 4:13:00 PM

0

On Sat, Mar 15, 2008 at 4:21 PM, Sean Allen <sean@ardishealth.com> 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 .... :(
Cheers
Robert
--
http://ruby-smalltalk.blo...

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