Let's start off by saying I'm not anti-Ruby. I like Ruby. Ruby is cool. Matz is cool. But, a while back I was wondering, What is a Ruby code block? My feeble curiosity has been revealed for the half-assed dilettantery it is by Paul Cantrell. Mr. Cantrell chases this question down, grabs it by the scruff of the neck, and wrings it out like a bulldog with a new toy. He also rocks on the piano, by the way.
So in fact, there are no less than seven -- count 'em, SEVEN -- different closure-like constructs in Ruby:
- block (implicitly passed, called with yield)
- block (&b => f(&b) => yield)
- block (&b => b.call)
- Proc.new
- proc
- lambda
- method
This is quite a dizzing array of syntactic options, with subtle semantics differences that are not at all obvious, and riddled with minor special cases. It's like a big bear trap from programmers who expect the language to just work. Why are things this way? Because Ruby is:
- designed by implementation, and
- defined by implementation.
Again, neither I nor Mr. P.C. are bashing Ruby. He shows how to pull off some tasty functional goodness like transparent lazy lists later in the article. Thanks to railspikes for the link.




R Bloggers
That doesn't look like seven different closure constructs to me. It looks like three different ways to pass and/or call a block, two different ways to create a Proc, then lambda and Method - four different constructs. I didn't know the differences between any them until I read this article, but now it seems fairly clear.
ReplyDeleteDiscussed on hacker news:
ReplyDeletehttp://news.ycombinator.com/item?id=1241780