Ruby opinions (111)

105 Name: dmpk2k!hinhT6kz2E : 2007-11-10 21:11 ID:Heaven

Let's talk Ruby's blocks, since they're a feature that is routinely brought up as a point in Ruby's favour. Since the rest of Ruby has broken lexical scoping and no first-class functionsmethods -- a rant for another day if someone asks -- blocks are Ruby's claim to fame.

Ruby borrowed the idea of blocks from Smalltalk. That was probably a good idea. Unfortunately, like almost everything else in Ruby, they're half baked.

First up, lexical scoping. Blocks come pretty close to behaving as they should here. Just one problem:

y = 0                     
[ 'o shi' ].map { |y| puts y } => 'o shi'
puts y => 'o shi' (should be 0)

Given that the argument to the block, y, is in a different scope to the y outside, you'd expect that after this chunk of code is executed, y would still be 0. No, it's 'o shi'. So arguments to a block stomp all over variables in outer scopes.

The next (much smaller) problem is that blocks are not first-class objects:

x = { |y| }
SyntaxError: compile error
(irb):1: syntax error, unexpected '|', expecting '}'
x = { |y| }
^
from (irb):1

Nope.

In Smalltalk they were first-class objects, but in Ruby procs are. One consequence is that there's no way to pass multiple blocks to a method short of converting them to procs first. Why the nuance? Who knows!

(I suspect it's partly because Ruby's grammar is foobar and uses {} for both blocks and hashes. The more worrisome part is that the performance characteristics are substantially different, which possibly hints at different means of implementation.)

See >>50 for another reason why I am not in favour of this in Ruby. If you want an example of a language that has the whole lexical scoping and first-class everything right, see Lua.

Name: Link:
Leave these fields empty (spam trap):
More options...
Verification: