While the Internet is teeming with resources lauded by the countless Groovy metaprogramming capabilities, I have yet to find something close to a comprehensive best practice guide for actually using such features.
Beyond the typical overuse warning, the overuse warning is the most specific tip I've read suggests using categories to increase metaclasses whenever possible (which is actually just another way to reinforce the old "limited scope" idiom).
Common sense was sufficient for my trivial projects, but I'm increasingly worried about building from potentially poor / dissenting precedents when I solve more ambitious tasks.
Thus, I would really appreciate any advice, resources, or specific Groovy examples (or even the agnostic language β my admittedly brief experience with Ruby left me just as desirable) for metaprogramming best practices.
To clarify this topic, I will introduce a (very) simplified Rational project that could use metaprogramming in several ways:
@Immutable class Rational{
int num, den
Rational multiply(Integer v){
new Rational(num:num*v, den:den)
}
}
assert new Rational(num:1, den:2) * 3 == new Rational(num:3, den:2)
However, the attempt 3*new Rational(num:1, den:2)obviously threw a MissingMethodException.
The simplest and possibly least fragile means of adding a communicative property is with a static initializer block in the Rational class:
static {
Integer.metaClass.multiply = {Rational fraction -> fraction*delegate}
}
...
assert 3*new Rational(num:1, den:2) == new Rational(num:3, den:2)
, , .
, , - :
class BootStrap{
static void initialize(){
Integer.metaClass.multiply = {Rational fraction -> fraction*delegate}
}
}
(), . , , .
. , :
@Category(Integer) class RationalCategory{
Rational multiply(Rational frac){
frac*this
}
}
use(RationalCategory){
assert 3*new Rational(num:1, den:2) == new Rational(num:3, den:2)
}
, , , , , . , . , 1 2 "", Integer, .
- / ? , , - ? ( , .)