Sponsored Link •
Bill Venners: What makes a block a closure?
Yukihiro Matsumoto: A closure object has code to run, the executable, and state around the code, the scope. So you capture the environment, namely the local variables, in the closure. As a result, you can refer to the local variables inside a closure. Even after the function has returned, and its local scope has been destroyed, the local variables remain in existence as part of the closure object. When no one refers to the closure anymore, it's garbage collected, and the local variables go away.
Bill Venners: So the local variables are basically being shared between the closure and the method? If the closure updates the variable, the method sees it. And if the method updates the variable, the closure sees it.
Yukihiro Matsumoto: Yes, local variables are shared between the closure and the method. It's a real closure. It's not just a copy.
Bill Venners: What is the benefit of a real closure? Once I make a block into an object, what can I do with it?
Yukihiro Matsumoto: You can reconvert a closure back into a block, so a closure can be used anywhere a block can be used. Often, closures are used to store the status of a block into an instance variable, because once you convert a block into a closure, it is an object that can by referenced by a variable. And of course closures can be used like they are used in other languages, such as passing around the object to customize behavior of methods. If you want to pass some code to customize a method, you can of course just pass a block. But if you want to pass the same code to more than two methods -- this is a very rare case, but if you really want to do that -- you can convert the block into a closure, and pass that same closure object to multiple methods.
Bill Venners: OK, but what is the benefit of having the context? The distinction that makes Ruby's closure a real closure is that it captures the context, the local variables and so on. What benefit do I get from having the context in addition to the code that I don't get by just being able to pass a chunk of code around as an object?
Yukihiro Matsumoto: Actually, to tell the truth, the first reason is to respect the history of Lisp. Lisp provided real closures, and I wanted to follow that.
Bill Venners: One difference I can see is that data is actually shared between the closure objects and the method. I imagine I could always pass any needed context data into a regular, non-closure, block as parameters, but then the block would just have a copy of the context, not the real thing. It's not sharing the context. Sharing is what's going on in a closure that's different from a plain old function object.
Yukihiro Matsumoto: Yes, and that sharing allows you to do some interesting code demos, but I think it's not that useful in the daily lives of programmers. It doesn't matter that much. The plain copy, like it's done in Java's inner classes for example, works in most cases. But in Ruby closures, I wanted to respect the Lisp culture.
Come back Monday, December 29 for part IV of this conversation with Yukihiro Matsumoto. If you'd like to receive a brief weekly email announcing new articles at Artima.com, please subscribe to the Artima Newsletter.
Ruby in a Nutshell, by Yukihiro Matsumoto,
is available on Amazon.com at:
Programming Ruby: A Pragmatic Programmer's Guide, by Dave Thomas and Andy Hunt,
is available on Amazon.com at:
The Ruby Programming Language, an introduction by Yukihiro Matsumoto:
An Interview with the Creator of Ruby, by Bruce Stewart:
Interview with Ruby Create Y. Matsumoto, by S. Ibaraki: