//WOW! https://gist.github.com/3002724 // No commas def a = 'tim' def nocom = match( a ) { when 'dave' 'Hi Dave' when 'tim' 'Hi Tim' otherwise 'none of the above' } assert nocom == 'Hi Tim' // Commas a = 'William' def com = match( a ) { when 'dave', 'Hi Dave' when 'tim', 'Hi Tim' otherwise 'none of the above' } assert com == 'none of the above' // Lists (can't use commas) a = [1,3] def list = match( a ) { when [1,2] 'One and two' when [1,3] 'One and three' when [2,1] 'Two and one' } assert list == 'One and three' // Wildcard Lists (can't use commas) a = [1,2,3] def wild = match( a ) { when [1,3,2] 'One, three and two' when [1,_] 'One and something' when [1,_,3] 'One, something and three' when [1,_,_] 'One, something and something' otherwise 'Something else' } assert wild == 'One, something and three' // Closures as the when/results String toRoman( int num ) { match( num ) { when { it >= 100 } { "C" + toRoman( num - 100 ) } when { it >= 90 } { "XC" + toRoman( num - 90 ) } when { it >= 50 } { "L" + toRoman( num - 50 ) } when { it >= 40 } { "XL" + toRoman( num - 40 ) } when { it >= 10 } { "X" + toRoman( num - 10 ) } when { it >= 9 } { "IX" + toRoman( num - 9 ) } when { it >= 5 } { "V" + toRoman( num - 5 ) } when { it >= 4 } { "IV" + toRoman( num - 4 ) } when { it >= 1 } { "I" + toRoman( num - 1 ) } otherwise "" } } assert "I" == toRoman( 1 ) assert "II" == toRoman( 2 ) assert "IV" == toRoman( 4 ) assert "V" == toRoman( 5 ) assert "VI" == toRoman( 6 ) assert "IX" == toRoman( 9 ) assert "X" == toRoman( 10 ) assert "XVII" == toRoman( 17 ) assert "XXXVIII" == toRoman( 38 ) assert "CCCXCIX" == toRoman( 399 ) /////////////////////////// // Implementation below... def match( v, c ) { new Matcher( var:v, closure:c ).match() } class Matcher { def var Closure closure Listcases = [] Otherwise otherwise def propertyMissing( name ) { if( name == '_' ) { new Any() } else { def w = new When() cases << w w } } def when( condition ) { cases << new When( condition:condition ) } def when( condition, result ) { cases << new When( condition:condition, result:result ) } def otherwise( result ) { this.otherwise = new Otherwise( result:result ) } public match() { closure.delegate = this closure.resolveStrategy = Closure.DELEGATE_ONLY closure() def ret = cases.find { it.condition instanceof Closure ? it.condition( var ) : it.condition == var }?.result ?: otherwise?.result ret instanceof Closure ? ret() : ret } } class When { def condition def result def getAt( List a ) { condition = a ; this } def call( result ) { this.result = result } def propertyMissing( String result ) { this.result = result } } class Otherwise { def result } class Any { boolean equals( other ) { true } } println 'DONE'
Wednesday, August 1, 2012
match/when implemented with Groovy's GEP-3
Subscribe to:
Posts (Atom)