Last active
May 15, 2018 04:30
-
-
Save nobeans/0655a131ab3c458f99916655809bd547 to your computer and use it in GitHub Desktop.
GroovyのTraitのコーナーケースを踏んだ?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// in Groovy 2.4.14 | |
import groovy.transform.CompileStatic | |
// このようなprivate staticメソッドを使うメソッドをもつtraitに対して... | |
@CompileStatic | |
trait Trait { | |
String traitMethod() { _traitMethod() } | |
private static String _traitMethod() { "TRAIT" } | |
} | |
// 直接traitを実装するとなにも問題ない | |
@CompileStatic | |
class TraitImpl implements Trait { | |
String traitImplMethod() { "IMPL-${traitMethod()}" } | |
} | |
assert new TraitImpl().traitImplMethod() == "IMPL-TRAIT" | |
// 一段クラス階層を経由すると使うと... | |
@CompileStatic | |
class Parent implements Trait { | |
String parentMethod() { "PARENT-${traitMethod()}" } | |
} | |
@CompileStatic | |
class Child extends Parent { | |
String childMethod() { "CHILD-${parentMethod()}" } | |
} | |
GroovyAssert.shouldFail(MissingMethodException) { | |
assert new Child().childMethod() == "CHILD-PARENT-TRAIT" | |
} | |
// => trait上のprivate staticメソッドが見つからなくなる! | |
// groovy.lang.MissingMethodException: No signature of method: Child._traitMethod() is applicable for argument types: () values: [] | |
// Possible solutions: traitMethod(), parentMethod() | |
// at Trait$Trait$Helper.traitMethod(ConsoleScript35:5) | |
// at Parent.traitMethod(ConsoleScript35) | |
// at Parent.parentMethod(ConsoleScript35:19) | |
// at Child.childMethod(ConsoleScript35:23) | |
// at Child$childMethod.call(Unknown Source) | |
// at ConsoleScript35.run(ConsoleScript35:26) | |
// privateではないstaticだったり、staticではないprivateだったりすれば問題ない。 | |
@CompileStatic | |
trait Trait2 { | |
String traitMethod() { _traitMethod() } | |
static String _traitMethod() { "TRAIT" } | |
} | |
@CompileStatic | |
class Parent2 implements Trait2 { | |
String parentMethod() { "PARENT-${traitMethod()}" } | |
} | |
@CompileStatic | |
class Child2 extends Parent2 { | |
String childMethod() { "CHILD-${parentMethod()}" } | |
} | |
assert new Child2().childMethod() == "CHILD-PARENT-TRAIT" | |
@CompileStatic | |
trait Trait3 { | |
String traitMethod() { _traitMethod() } | |
private String _traitMethod() { "TRAIT" } | |
} | |
@CompileStatic | |
class Parent3 implements Trait3 { | |
String parentMethod() { "PARENT-${traitMethod()}" } | |
} | |
@CompileStatic | |
class Child3 extends Parent3 { | |
String childMethod() { "CHILD-${parentMethod()}" } | |
} | |
assert new Child3().childMethod() == "CHILD-PARENT-TRAIT" | |
// ちなみに宗教上の理由でCompileStaticをつけているけれど、外しても事象は同じ。 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment