Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
1.6
-
None
-
This is seen in groovy 1.6.0 on Leopard:
% groovy -version
Groovy Version: 1.6.0 JVM: 1.6.0_07
Description
I'm running into an issue with Groovy 1.6 trying to add a static method to the metaClass where the closure for the method has some parameters with default values.
When trying to call the method and not supplying some default values, it doesn't find the newly added method and instead throws a MissingMethodException.
Default parameters work fine with a class where the static method is defined directly on the class, both through using a closure as well as a normal method definition:
class MyClass {
def testInstance(first = "foo")
static testStatic(first = "foo") { return "$first" }
static testStaticClosure =
{ first = "foo" -> return "$first" }
static testStaticTwoParms(first = "foo", second = "bar")
{ return "$first - $second" }static testStaticTwoParmsClosure =
{ first = "foo", second = "bar" -> return "$first - $second" }
}
assert "foo" == new MyClass().testInstance()
assert "foo" == MyClass.testStatic()
assert "foo" == MyClass.testStaticClosure()
assert "foo - bar" == MyClass.testStaticTwoParms()
assert "foo - bar" == MyClass.testStaticTwoParmsClosure()
Using the metaClass, it works fine to add instance methods with single or multiple defaulted values:
String.metaClass.testInstance =
{ first = "foo" -> return "$first" }assert "foo" == "".testInstance() // works as expected
String.metaClass.testInstanceTwoParams = { first = "foo", second = "bar" -> return "$first - $second" }
assert "foo - bar" == "".testInstanceTwoParams() // also works as expected
But when a static method is added to a class via the metaClass, a single default parameter doesn't use the default value for the paramter, it has a null value:
String.metaClass.'static'.testStatic = { first = "foo" -> return "$first" }
assert "qux" == "".testStatic("qux") // works if you specify a parameter
assert "foo" == "".testStatic() // Fails! "foo" isn't returned, instead it returns a null value
It gets weirder if you try to specify two defaulted parameters on the static closure. Instead of just not assigning values to the parameters, it doesn't even find the method and throws a MissingMethodException:
String.metaClass.'static'.testStaticTwoParams =
{ first = "foo", second = "bar" -> return "$first - $second" } assert "baz - qux" == "".testStaticTwoParams("baz", "qux") // works if you specify parameters
assert "baz - bar" == "".testStaticTwoParams("baz") // Fails with MissingMethodException!
assert "foo - bar" == "".testStaticTwoParams() // Fails with MissingMethodException! Not finding method with defaulted pararameters
This is seen in groovy 1.6.0:
% groovy -version
Groovy Version: 1.6.0 JVM: 1.6.0_07
I also tested this code against 1.5.7 and it exhibits the same behavior, but is also broken for metaClass added instance methods with defaulted values, which work in 1.6. Hopefully whatever was changed in 1.6 to fix that can also be applied to class level static methods.