RudolphEst RudolphEst - 1 year ago 104
Groovy Question

Use groovy categories to add dynamic properties

Expanding on this blog post, I am trying to use a category to create a simple DSL for use with the

(JSR-275) classes (similar to TimeCategory for time intervals)

However, I do not want to add boilerplate code for each of the possible available methods (getMeter, getMilliMeter, getKelvin, getSecond etc.). I thought overriding the
method would work, but alas, it looks like the
method defined in the category is not used when accessing the property directly.

Here is some simplified code to demonstrate:
import javax.measure.quantity.Length;
import javax.measure.unit.Unit;
import javax.measure.Measure;

class LengthCategory {
public Measure<BigDecimal, Length> getProperty(String unit){
return Measure.valueOf(this,Unit.valueOf(unit));

println 3.getProperty("m") // this works
println 3.m // this reports a non-exisiting property
prinlln 3.'m' // as does this

Assuming other methods of dynamically adding properties to a runtime object (e.g.
, subclassing
, mixins and other metaclass manipulations) is not viable and I would really rather not have to manually code getters for every possible unit and SI prefix combination. There are obviously other ways to go about creating a DSL for measurements, but I would still like to understand why this method would not work.

Could someone explain why the
method of the category does not override
usage? I am obviously missing something important about the resolution of property names using the metaclass during runtime.

Answer Source

I don't know why getProperty doesn't work on categories. But you can define a get method on them that does basically the same (i think). This works:

class LengthCategory {      
    def get(String unit) {
        "$this $unit"

use (LengthCategory) {
    println 3.m   // 3 m
    println 3.'m' // 3 m