Using Java get, set, and is methods as Gosu properties

Gosu can call methods on Java types. For methods on Java types that look like getters and setters, Gosu exposes the methods instead as properties. Gosu uses the following rules for methods on Java types:

  • If the method name starts with set and takes exactly one argument, Gosu exposes it as a setter for a property. The property name matches the original method but without the prefix set. For example, if the Java method signature is setName(String thename), Gosu exposes this method as a property setter method for the property called Name.
  • If the method name starts with get, takes no arguments, and returns a value, Gosu exposes it as a getter for a property. The property name matches the original method but without the prefix get. For example, if the Java method with signature getName() returns a String value, Gosu exposes this method as a property getter method for the property named Name of type String.
  • Similar to the rules for get, if the method name starts with is, takes no arguments, and returns a Boolean value, Gosu exposes it as a property getter. The property name matches the original method but without the prefix is. For example, if the Java method with signature isVisible() returns a Boolean value, Gosu exposes the method as a property getter method for the Boolean property named Visible.
  • Gosu makes these transformations on static methods as well as on instance methods.
  • Even though Gosu provides a property that you can access for reading and writing information, Gosu does not prevent use of the getter and setter methods. For example, if a Java object has an getName method, you can use the expression obj.Name or obj.getName().
  • If the class has a setter and a getter, Gosu makes the property readable and writable. If the setter is absent, Gosu makes the property read-only. If the getter is absent, Gosu makes the property write-only.
Note: If the Java class has a public variable that has the same name as a property that Gosu converts from getter or setter methods, the class definition is ambiguous to Gosu. Gosu cannot determine whether to use the methods or the variable. For example, if your Java class has a public variable, X, and a public method, setX that sets the value of the private variable _x, the behavior of reading or writing the property, X is undefined. You must call the getter and setter methods directly instead of using property syntax. To access the ambiguous variable, use reflection.

Example: Using Java methods as properties in Gosu

This Java class defines multiple methods that Gosu can convert to properties:

package doc.example;

public class Circle {
  public static final double PI = Math.PI;
  private double _radius;

  // Constructor #1 - no arguments
  public Circle() {
  }

  // Constructor #2
  public Circle(int dRadius) {
    _radius = dRadius;
  }

  // From Java, these are METHODS that begin with get, set, is.
  // From Gosu, these are PROPERTY accessors.

  public double getRadius() {
    System.out.println("Running Java METHOD getRadius()");
    return _radius;
  }
  public void setRadius(double dRadius) {
    System.out.println("Running Java METHOD setRadius()");
    _radius = dRadius;
  }
  public double getArea() {
    System.out.println("Running Java METHOD getArea()");
    return PI * getRadius() * getRadius();
  }
  public double getCircumference() {
    System.out.println("Running Java METHOD getCircumference()");
    return 2 * PI * getRadius();
  }

  public boolean isRound() {
    System.out.println("Running Java METHOD isRound()");
    return(true);
  }

  // The following methods remain methods, and do not convert to properties.

  // For GET/IS, the method must take 0 arguments and return a value
  public void isMethod1() {
    System.out.println("Running Java METHOD isMethod1()");
  }
  public double getMethod2(double a, double b) {
    System.out.println("Running Java METHOD isMethod2()");
    return 1;
  }

  // For SET, the method must take 1 argument and return void
  public void setMethod3() {
    System.out.println("Running Java METHOD setMethod3()");
  }
  public double setMethod4(double a, double b) {
    System.out.println("Running Java METHOD setMethod4()");
    return 1;
  }
}

The following Gosu code uses this Java class. Note which Java methods become property accessors and which ones do not.

// Instantiate the class with the constructor that takes an argument
var c = new doc.example.Circle(10)

// Use natural property syntax to SET GOSU PROPERTIES. In Java, this was a method.
c.Radius = 10

// Use natural property syntax to GET GOSU PROPERTIES
print("\tRadius: " + c.Radius)
print("\tArea: " + c.Area)
print("\tRound: " + c.Round) // boolean true coerces to String "true"
print("\tCircumference: " + c.Circumference)

// The following assignments cause syntax errors if you uncomment them.
// They are not writable—there is no setter method.
//
// c.Area = 3 
// c.Circumference = 4 
// c.Round = false 

// These Java methods do not convert to properties because
// they have the wrong number of arguments or the wrong types.
c.isMethod1()
var temp2 = c.getMethod2(1,2)
c.setMethod3()
var temp4 = c.setMethod4(8,9)

This Gosu code prints the following:

Running Java METHOD setRadius()
Running Java METHOD getRadius()
    Radius: 10
Running Java METHOD getArea()
Running Java METHOD getRadius()
Running Java METHOD getRadius()
    Area: 314.1592653589793
Running Java METHOD isRound()
    Round: true
Running Java METHOD getCircumference()
Running Java METHOD getRadius()
    Circumference: 62.83185307179586
Running Java METHOD isMethod1()
Running Java METHOD isMethod2()
Running Java METHOD setMethod3()
Running Java METHOD setMethod4()