Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

groovy.lang.Binding difference between property and variable

Tags:

java

groovy

Couldn't really figure out/find what a difference between thouse two

import groovy.lang.Binding;
import groovy.lang.GroovyShell;

class Scratch {
    public static void main(String[] args) {
        Binding binding = new Binding();
        Integer p = 1,
                v = 1;
        binding.setProperty("p", p);
        binding.setVariable("v", v);

        GroovyShell shell = new GroovyShell(binding);
        shell.evaluate("p++;v++;");
        System.out.println(String.format("BINDING Property = %s, Variable = %s", binding.getProperty("p"), binding.getVariable("v")));
        System.out.println(String.format("JAVA Property = %s, Variable = %s", p, v));
    }
}

Output is:

BINDING Property = 2, Variable = 2
JAVA Property = 1, Variable = 1

Is there is some purpose for using one or another.

like image 224
Ivan Baranuk Avatar asked Dec 03 '18 12:12

Ivan Baranuk


People also ask

What is binding in Groovy?

The binding is defined in the Groovy API documentation as follows: “Represents the variable bindings of a script which can be altered from outside the script object or created outside of a script and passed into it.”.

What is a property in Groovy?

When a Groovy class definition declares a field without an access modifier, then a public setter/getter method pair and a private instance variable field is generated which is also known as "property" according to the JavaBeans specification.

What is Groovyshell?

A Groovy shell is a command-line application that lets you evaluate Groovy expressions, functions, define classes and run Groovy commands. The Groovy shell can be launched in Groovy projects.

What is Groovy VAR?

From Groovy documentation: Variables can be defined using either their type (like String ) or by using the keyword def (or var ) followed by a variable name, def and var act as a type placeholder, i.e. a replacement for the type name, when you do not want to give an explicit type: String x def y var z.


1 Answers

The class groovy.lang.Binding overloads setProperty and getProperty methods so you can access variables using field accessor or subscript operator. If you take a look at the source code of these two methods you will find something like this:

/**
 * Overloaded to make variables appear as bean properties or via the subscript operator
 */
public Object getProperty(String property) {
    /** @todo we should check if we have the property with the metaClass instead of try/catch  */
    try {
        return super.getProperty(property);
    }
    catch (MissingPropertyException e) {
        return getVariable(property);
    }
}

/**
 * Overloaded to make variables appear as bean properties or via the subscript operator
 */
public void setProperty(String property, Object newValue) {
    /** @todo we should check if we have the property with the metaClass instead of try/catch  */
    try {
        super.setProperty(property, newValue);
    }
    catch (MissingPropertyException e) {
        setVariable(property, newValue);
    }
}

It means that in Groovy you could express

binding.setVariable("v", v);

as

binding.v = v
// or
binding['v'] = v

Of course if the property you are accessing with setProperty or getProperty exists in the class, then you won't be able to set a variable using this name and in this case, you need to call binding.setVariable() directly.

On the other hand, methods getVariable and setVariable reads or puts values directly to the internal map. Here is what its source code looks like:

/**
 * @param name the name of the variable to lookup
 * @return the variable value
 */
public Object getVariable(String name) {
    if (variables == null)
        throw new MissingPropertyException(name, this.getClass());

    Object result = variables.get(name);

    if (result == null && !variables.containsKey(name)) {
        throw new MissingPropertyException(name, this.getClass());
    }

    return result;
}

/**
 * Sets the value of the given variable
 *
 * @param name  the name of the variable to set
 * @param value the new value for the given variable
 */
public void setVariable(String name, Object value) {
    if (variables == null)
        variables = new LinkedHashMap();
    variables.put(name, value);
}
like image 197
Szymon Stepniak Avatar answered Nov 01 '22 00:11

Szymon Stepniak