[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Help with a ruby idiom

Tim Waters

12/23/2006 4:03:00 PM

From the O'Reilly Cookbook there is code that keeps call functions in a
hash as a subscriber/listener type pattern. What I don't understand (or
I don't understand how it works is the line:
(@EventDispatcher_listeners[event] ||= []) << callback


module EventDispatcher
def setup_listeners
@EventDispatcher_listeners = {}
end

def subscribe(event, &callback)
(@EventDispatcher_listeners[event] ||= []) << callback
end

protected
def notify(event, *args)
if @EventDispatcher_listeners[event]
@EventDispatcher_listeners[event].each do |m|
m.call(*args) if m.respond_to? :call
end
end
return nil
end
end

--
Posted via http://www.ruby-....

17 Answers

Vincent Fourmond

12/23/2006 4:09:00 PM

0

Tim Waters wrote:
>>From the O'Reilly Cookbook there is code that keeps call functions in a
> hash as a subscriber/listener type pattern. What I don't understand (or
> I don't understand how it works is the line:
> (@EventDispatcher_listeners[event] ||= []) << callback

You can split it into two, which will make it more clear:

@EventDispatcher_listeners[event] ||= [] # makes it an empty array if
it doesn't exist
@EventDispatcher_listeners[event] << callback # and pushes the callback
on top of it

I agree that this kind of compact notation is very hand but slightly
indecipherable... Cheers,

Vince

--
Vincent Fourmond, PhD student
http://vincent.fourmon...

Robert Klemme

12/23/2006 4:12:00 PM

0

On 23.12.2006 17:02, Tim Waters wrote:
> From the O'Reilly Cookbook there is code that keeps call functions in a
> hash as a subscriber/listener type pattern. What I don't understand (or
> I don't understand how it works is the line:
> (@EventDispatcher_listeners[event] ||= []) << callback

a ||= b

is equivalent to

a || (a = b)

IOW

a = b unless a

IOW

unless a
a = b
end

IOW

"eval b and assign the result to a if a is nil or false".

In this case, since a Hash is also involved the lengthy form looks like
this:

unless @EventDispatcher_listeners[event]
@EventDispatcher_listeners[event] = []
end
@EventDispatcher_listeners[event] << callback

I hope you admit that ||= is much more concise and elegant. :-)

HTH

robert

matt

12/23/2006 4:13:00 PM

0

Tim Waters <timgwaters@gmail.com> wrote:

> What I don't understand (or
> I don't understand how it works is the line:
> (@EventDispatcher_listeners[event] ||= []) << callback

Here is a verbose a description:

@EventDispatcher_listeners is a hash.

Look up the entry in that hash, the entry named "event".

But perhaps there is no such entry. (The entry is reported as nil.) In
that case, create one, and set it to be an empty array.

Now you have an array - either the array that was already the "event"
entry in the hash, or the empty array that is now the "event" entry in
the hash. Append "callback" as the last item of that array.

m.
--
matt neuburg, phd = matt@tidbits.com, http://www.tidbits...
Tiger - http://www.takecontrolbooks.com/tiger-custom...
AppleScript - http://www.amazon.com/gp/product/...
Read TidBITS! It's free and smart. http://www.t...

Tim Waters

12/23/2006 4:39:00 PM

0

Robert Klemme wrote:
> I hope you admit that ||= is much more concise and elegant. :-)
>
> HTH
>
> robert

Thanks to all, I think I understand now. And yes, it is QUITE concise!
-tim


--
Posted via http://www.ruby-....

dblack

12/23/2006 6:55:00 PM

0

Devin Mullins

12/23/2006 7:02:00 PM

0

dblack@wobblini.net wrote:
> It is indeed functionally equivalent to those, though all of them
> would blow up :-)
Not all of them.
a = b unless a
works, for the same reason you described
a = a || b
working. Here, the "a =" is parsed before the "unless a" is evaluated.

But yes, a ||= b maps more closely to a = a || b, just like a += b maps
to a = a + b.

Devin
(Though, I tend to use the ||= idiom most often with instance/class
variables, who don't raise NameError like locals do.)

dblack

12/23/2006 7:04:00 PM

0

M. Edward (Ed) Borasky

12/23/2006 7:31:00 PM

0

dblack@wobblini.net wrote:
> Hi --
>
> On Sun, 24 Dec 2006, Devin Mullins wrote:
>
>> dblack@wobblini.net wrote:
>>> It is indeed functionally equivalent to those, though all of them
>>> would blow up :-)
>> Not all of them.
>> a = b unless a
>> works, for the same reason you described
>> a = a || b
>> working. Here, the "a =" is parsed before the "unless a" is evaluated.
>
> Whoops, right; thanks.
>
>
> David
>
Might I be a curmudgeon on this Christmas eve eve? I say that any idiom
that's confusing enough that its semantics isn't *instantly*
recognizable to an old FORTRAN programmer like my curmudgeonly self
probably doesn't contribute to code readability. :) So I would write
this out in "longhand" and not let the parser have an opportunity to
confuse me. So my "idiom" would be

if (!a) then
a = b
end

Or, since my curmudgeonly self has managed to learn Perl, :)

a = b if !a



--
M. Edward (Ed) Borasky, FBG, AB, PTA, PGS, MS, MNLP, NST, ACMC(P)
http://borasky-research.blo...

If God had meant for carrots to be eaten cooked, He would have given rabbits fire.


dblack

12/23/2006 8:22:00 PM

0

William James

12/23/2006 8:32:00 PM

0

M. Edward (Ed) Borasky wrote:
> dblack@wobblini.net wrote:
> > Hi --
> >
> > On Sun, 24 Dec 2006, Devin Mullins wrote:
> >
> >> dblack@wobblini.net wrote:
> >>> It is indeed functionally equivalent to those, though all of them
> >>> would blow up :-)
> >> Not all of them.
> >> a = b unless a
> >> works, for the same reason you described
> >> a = a || b
> >> working. Here, the "a =" is parsed before the "unless a" is evaluated.
> >
> > Whoops, right; thanks.
> >
> >
> > David
> >
> Might I be a curmudgeon on this Christmas eve eve? I say that any idiom
> that's confusing enough that its semantics isn't *instantly*
> recognizable to an old FORTRAN programmer like my curmudgeonly self
> probably doesn't contribute to code readability. :) So I would write
> this out in "longhand" and not let the parser have an opportunity to
> confuse me. So my "idiom" would be
>
> if (!a) then
> a = b
> end
>
> Or, since my curmudgeonly self has managed to learn Perl, :)
>
> a = b if !a

a = b unless a