Understanding Ruby Blocks, Procs and Lambdas
robertsosinski.com
Understanding Ruby Blocks, Procs and Lambdas
1–9 of 9 posts
Re: Understanding Ruby Blocks, Procs and Lambdas
#2And the much cooler Fibers, which you can think of as a reentrant block, kind of.
Re: Understanding Ruby Blocks, Procs and Lambdas
#3Is it simply to allow for the magic syntax of passing a block to a method so it can be called with yield?
Re: Understanding Ruby Blocks, Procs and Lambdas
#4I still don't understand Procs and Lambdas but my head is too full today, will finish reading your post tomorrow.
As a side note, please enable comments, I'd love to leave you some good feedback on your actual site.
Re: Understanding Ruby Blocks, Procs and Lambdas
#5What's the reason for blocks not being real objects (i.e. Procs) themselves (like in JavaScript or Lisp)? Is it simply to allow for the magic syntax of passing a block to a method so it can be called with yield?
If you had a block that was an actual object, it could outlive its enclosing environment. Calling return within it would reincarnate its enclosing environment. Calling return twice would fork time.
In other words, if a block was an object, the return keyword would create a continuation. This is a very expensive, very heavyweight feature in Ruby, and the whole point of blocks is to provide something cheap and lightweight.
Note that a proc or lambda has no such problem, since a return within it returns to whatever invokes the #call method of the proc or lambda.
Imagine how much simpler things would be if Matz had worked this all out and decided that the return keyword was more trouble than it was worth?
Re: Understanding Ruby Blocks, Procs and Lambdas
#6What's the reason for blocks not being real objects (i.e. Procs) themselves (like in JavaScript or Lisp)? Is it simply to allow for the magic syntax of passing a block to a method so it can be called with yield?
Most of the problem is the `return` keyword. In a proc or lambda, it returns from the proc or lambda. In a block, it returns from whatever is enclosing the block, like a proc, lambda, or method. If you had a block that was an actual object, it could outlive its enclosing environment. Calling return within it would reincarnate its enclosing environment. Calling return twice would fork time. In other words, if a block…
"return false if simple_question?" ... rest of the body
is a very useful thing to do. granted, you might say it is "programming by GOTO", but it lowers the indentation level, and so keeps me happy.
To the GP: we can also .to_proc on blocks.
Re: Understanding Ruby Blocks, Procs and Lambdas
#7What's the reason for blocks not being real objects (i.e. Procs) themselves (like in JavaScript or Lisp)? Is it simply to allow for the magic syntax of passing a block to a method so it can be called with yield?
You can no longer call yield(...) but instead you have to use bl.call(...)
You can indeed save the Proc object and use it later.
Re: Understanding Ruby Blocks, Procs and Lambdas
#8Really? I thought this was the definitive guide: http://innig.net/software/ruby/closures-in-ruby.rb
It seems like a good guide to me.
Re: Understanding Ruby Blocks, Procs and Lambdas
#9Earlier quoted context omitted.
Most of the problem is the `return` keyword. In a proc or lambda, it returns from the proc or lambda. In a block, it returns from whatever is enclosing the block, like a proc, lambda, or method. If you had a block that was an actual object, it could outlive its enclosing environment. Calling return within it would reincarnate its enclosing environment. Calling return twice would fork time. In other words, if a block…
I respectfully disagree that the return keyword is more trouble than it is worth. "return false if simple_question?" ... rest of the body is a very useful thing to do. granted, you might say it is "programming by GOTO", but it lowers the indentation level, and so keeps me happy. To the GP: we can also .to_proc on blocks.
You can decide for yourself if this behaviour of return more trouble than it's worth. I didn't say it was, I said that this definition is what forces a block to be something different from a proc, which makes the language more complicated.