Note: This page may not follow the explanations from the JLS.
Java has two basic informal rules for scoping:
Principle #1: "A variable is only visible in the block it is defined in".
Principle #2: "A variable can't be visible more than one time".
Java does know classwide variables and local variables. Local variables are defined as method parameter or inside the method block. Classwide variables are defined as attribute of the class. Of course Java does violate this first principle I showed at top here a little since I can access class wide varibales from outside the class, if the access modifier is for example public. A local variable of the same name as an attribute does not violate the second principle, as the attribute is hidden by the local variable and with this no longer visible without using a qualifier lke "this".
Now, what about Groovy?
In Groovy we too have these two principles, but since we have different constrcuts, we may lay out these principles in a different way. Let us start with local variables. In Groovy you too are not allowed to define two local variables of the same name, you are allowed to hide an attribute, just like in Java.
So what is different?
Scripts are. When you define a variable in a script it is always local. But methods are not part of that scope. So defining a method using different varibales as if they were attributes and then defining these varibales normally in the script leads to problems. Example:
Executing this code you get an exception talking about a missing property or field. The only things the method has access to are the binding, attributes defined by the base class and the dynamic properties defined by the MetaClass (explanations for these will follow). "attribute" here is no field, no property, no dynamic defined property and not part of the binding.
When is something in the Binding and when not?
That's easy, when it is not defined, it is in the binding.
The trick is, and that is not easy for Java programers, to not to define the varibale before using it, and it will go into the binding. Any defined variable is local. Please note: the binding exists only for scripts.
What is this "def" I heard of?
"def" is a replacement for a type. Using it defines a variable. In case of a script a loacal variable, in case of a class either a property/field or a local variable. Think of "def" as an alias of "Object" and you will undestand it in an instant. Future Groovy may give "def" an additional meaning in terms of static and dynamic typing. But this is post Groovy 1.0.
The assignment of a number, such as 2, to a String typed variable will fail. A variable typed with "def" allows this.
"it" is a specail variable name, that is defined automatically inside a closure. It refers always to the first parameter of the closure, or nul, if the closure doesn't have any parameters
When using nested cosures (closures in closures) the meaning of "it" depends on the closure you are in.
You see, that "it" is used two times, the "it" in "inner" means the first parameter of the closure "inner", the following "it" means the first parameter of "outer". This hepls a lot when copying code from one place to another containing closure that are using it.