Expanding on this blog post, I am trying to use a category to create a simple DSL for use with the javax.measure
(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 getProperty(String)
method would work, but alas, it looks like the getProperty
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;
@Category(Number)
class LengthCategory {
public Measure<BigDecimal, Length> getProperty(String unit){
return Measure.valueOf(this,Unit.valueOf(unit));
}
}
use(LengthCategory){
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. Expando
, subclassing GroovyInterceptible
, 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 getProperty
method of the category does not override .propertyName
usage? I am obviously missing something important about the resolution of property names using the metaclass during runtime.
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:
@Category(Number)
class LengthCategory {
def get(String unit) {
"$this $unit"
}
}
use (LengthCategory) {
println 3.m // 3 m
println 3.'m' // 3 m
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With