Da Utorok 07 Februr 2006 18:38 Sam Kong napsal:
> Hello!
>
> I read an interview article with matz about closure.
> (http://www.artima.com/intv/closures2.html)
>
> He mentioned that Ruby's closure is a real closure like Lisp.
> Local variables are shared between a method and a closure.
>
> <snip>
> local variables are shared between the closure and the method. It's a
> real closure. It's not just a copy.
> ....
> 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
> </snip>
>
>
> Can somebody help me understand what he meant?
> Closures in other languages are different from Ruby?
> And if possible, I want to see the *interesting code demos".
>
> Thanks.
>
> Sam

A "closure" in Java is somewhat used when doing quick GUI hacks:

	class FooButton {
		private final String foo = "FOO";
		{
			this.addActionListener(new ActionListener() {
				public actionPerformer(ActionEvent e) {
					// Pop up a message box saying "FOO" when the button is pressed.
					JOptionPane.showMessageDialog(null, foo);
			});
		}
	}

You can only use variables declared as final inside the anonymous inner class 
(the ActionListener); what will be accessible inside the inner class code is 
a copy of the reference to foo.

That means you can't assign another String to the variable foo from inside the 
"closure" code. Java goes overkill here by making sure you can't possibly 
reassign something to foo at all after initialization.

Contrast this to Ruby:

	def do_yield()
		yield
	end

	foo = "FOO"
	do_yield() {
		foo = "BAR"
	}
	puts foo # Outputs "BAR".

Which means you can assign to local variables in the closure's lexical scope 
from inside the closure.

This is usually only really useful when implementing custom control structures 
- the #loop method comes to mind. The Smalltalk language made use of this 
extensively. Usually, it's much more cleaner and readable to structure your 
code so any result of the computation performed inside the block is returned 
as (part of) the result of the method you pass a block to - for example using 
#collect, #select, or #inject than using #each as you'd use a loop construct 
in for example Java.

David Vallner