Blocks may not themselves be objects but Ruby's object model is consistent.
> I found an article on style usage for these two. It suggests using braces for the case where you're using the resulting value of a call with a block for a subsequent call, and to use do-end when you're just executing a sequence of actions.
The idiomatic way to use them is to use braces when your block is a one-liner and do/end when it spans multiple lines. Thus:
foo.each {|e| puts e }
bar.each do |line|
print 'Enter the current color: '
puts line.gsub(/shade/, gets)
end
The article you linked mentions that in the first paragraph. The second just brings up someone's suggestion to use braces when the value is being used, which is not really so much idiomatic of the general consensus about how to use the language's syntax. While there are times when I would choose to diverge from such a consensus just because the alternative is a better idea, I don't think I agree this is one of those cases.
The only benefit I really see to taking the "braces for using the return value" approach is making things clearer to people used to other languages' syntax, but the goal I think should be to make things clear for people used to the current "alternately, we could get rid of 'foo' and just say: 1 to: 10 do: [ ... ] In the Ruby case, this would be equivalent to doing: 0..9.each { ... }"
Are you sure that wouldn't be more equivalent to this in Ruby?
1.upto(10) {|n| puts "do stuff with #{n}" }
The difference is perhaps subtle, and merely conceptual, but your Smalltalk seems more like the upto example than the range.each The "do:" message in the above Smalltalk code is sent to the array, containing the block as a parameter value. It does the same thing as "each" in Ruby. So in Smalltalk "do" is a message, but in Ruby, do-end is a construct that is translated into a block.
This does seem to suggest that your Ruby example is more equivalent to the Smalltalk example than my Ruby example. Does that mean that to: is a range constructor while do is an iterator, the way .. is a range constructor in Ruby while upto and each The reason I thought of adding the parentheses in my first comment is I'm used to blocks being objects in and of themselves that can receive their own messages, particularly in an OOP language.
In Ruby, the block itself is not an object. An object representing it is sent to the block-using method as an argument, though -- at least as I understand it. That makes it similar to a method or, more directly, a lambda in Ruby; it is not itself an object, but an object can be instantiated that represents it, and sometimes that happens implicitly.