Hacker News new | ask | show | jobs
by nlh 2067 days ago
> Blocks are one of the most confusing, yet most powerful elements of Ruby. They allow you to group expressions, save them to a variable, and even pass them to a method. I’m still getting used to blocks and realizing their usefulness, but overall I feel that they condense a lot of code, and also make code more reusable and extensible.

Agreed re: confusion! I've been using Ruby (and Crystal) for years and I'm only slightly ashamed to admit that while I fully understand how to _use_ blocks, I haven't really truly grokked them. I kinda use them and use yield and it all works.

But! Something clicked recently, and I'm not sure why it took so long (maybe it was lots more experience with JavaScript lately?) and I feel kinda dumb that I just realized this:

Blocks are just anonymous functions. That's it. Yield just means "call the anonymous function that was passed in". Yield with arguments (which always confused the hell out of me) is, again, just calling that same anonymous function with arguments.

(I think?)

4 comments

> Blocks are just anonymous functions. That's it.

Blocks in ruby have non-local return, unlike anonymous functions.

compare `[1,2,3].map {|e| return true if e > 1 }` in ruby to `[1,2,3].map(e => {if(e > 1) { return true}})` in javascript. The ruby version will return a single `true` value, while the javascript version will return an array.

This post walks through a example that resembles my experience writing bugs when I knew way more ruby than javascript: https://github.com/raganwald-deprecated/homoiconic/blob/mast...

Interesting! I recall reading about this before but I’d forgotten it.

And I suppose one of the things that trips people up a lot about ruby is that the implicit return gives a different result — eg your example but without the “return true if” part DOES return an array, like JavaScript.

yes, exactly! Anonymous functions weren't as common in other languages when Ruby first got popular, so the older Ruby devs had to learn about blocks without talking about anonymous functions, and I think they mostly haven't realized that the world has changed and there's a common terminology that people coming in from other languages will know.

The one big quirk is that Ruby syntax doesn't let you assign a block to a variable like you can assign a function to a variable in javascript. But you can work around that by using the lambda keyword or Proc.new with a block, which will wrap it into an object. Then you can use the & sigil to pass that object into a method that's expecting a block

What ruby blocks have in common with js anonymous functions is that they are closures, so that might be what made them click when you learned about those.
The only confusing and brittle thing is not being able to remember what the behavior of return is inside a block, price, or lambda