I have the following test:
===
package au.com.transentia.utils.test
public class FastSplitTest extends GroovyTestCase {
void setUp() {
String.metaClass.fastSplit = {delim, expected ->
def buffer = []
try {
StringTokenizer st = new StringTokenizer(delegate, delim);
for (int i = 0; i < expected; i++)
buffer[i] = st.nextToken();
return buffer.toArray();
}
catch (NoSuchElementException e) {
throw new NoSuchElementException("Could not successfully split line:
'" + line + "' into " + expected + " items delimited by '" + delim + "'");
}
}
String.metaClass.fastSplitComma4 = String.metaClass.fastSplit.curry(",",
4)
}
void testSplit() {
assertArrayEquals(['this', 'is', 'a', 'test'].toArray(),
"this,is,a,test".fastSplit(",", 4))
}
void testCurried() {
assertArrayEquals(['this', 'is', 'a', 'test'].toArray(),
"this,is,a,test".fastSplitComma4())
}
}
===
This gives:
===
"C:\Program Files\Java\jdk1.6.0_11\bin\java" -Didea.launcher.port=7551
"-Didea.launcher.bin.path=C:\Program Files\JetBrains\IntelliJ IDEA
8.0.1\bin" -Dfile.encoding=windows-1252 -classpath
"C:\DEVTOOLS\groovy-1.6-RC-1\embeddable\groovy-all-1.6-RC-1.jar;C:\Program
Files\Java\jdk1.6.0_11\jre\lib\charsets.jar;C:\Program
Files\Java\jdk1.6.0_11\jre\lib\deploy.jar;C:\Program
Files\Java\jdk1.6.0_11\jre\lib\javaws.jar;C:\Program
Files\Java\jdk1.6.0_11\jre\lib\jce.jar;C:\Program
Files\Java\jdk1.6.0_11\jre\lib\jsse.jar;C:\Program
Files\Java\jdk1.6.0_11\jre\lib\management-agent.jar;C:\Program
Files\Java\jdk1.6.0_11\jre\lib\plugin.jar;C:\Program
Files\Java\jdk1.6.0_11\jre\lib\resources.jar;C:\Program
Files\Java\jdk1.6.0_11\jre\lib\rt.jar;C:\Program
Files\Java\jdk1.6.0_11\jre\lib\ext\dnsns.jar;C:\Program
Files\Java\jdk1.6.0_11\jre\lib\ext\localedata.jar;C:\Program
Files\Java\jdk1.6.0_11\jre\lib\ext\sunjce_provider.jar;C:\Program
Files\Java\jdk1.6.0_11\jre\lib\ext\sunmscapi.jar;C:\Program
Files\Java\jdk1.6.0_11\jre\lib\ext\sunpkcs11.jar;C:\DEVELOPMENT\IntelliJ\FB\
out\production\FB;C:\DEVTOOLS\commons-lang-2.4\commons-lang-2.4.jar;C:\DEVTO
OLS\groovy-1.6-RC-1\lib\junit-3.8.2.jar;C:\Program Files\JetBrains\IntelliJ
IDEA 8.0.1\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain
com.intellij.rt.execution.junit.JUnitStarter -ideVersion5
au.com.transentia.utils.test.FastSplitTest
groovy.lang.MissingMethodException: No signature of method:
groovy.lang.ExpandoMetaClass$ExpandoMetaProperty.curry() is applicable for
argument types: (java.lang.String, java.lang.Integer) values: {,, 4}
at
org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapt
er.java:54)
at
org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSit
e.java:51)
at
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray
.java:43)
at
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.
java:116)
at
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.
java:128)
at
au.com.transentia.utils.test.FastSplitTest.setUp(FastSplitTest.groovy:21)
at
com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl
.java:25)
at
com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
groovy.lang.MissingMethodException: No signature of method:
groovy.lang.ExpandoMetaClass$ExpandoMetaProperty.curry() is applicable for
argument types: (java.lang.String, java.lang.Integer) values: {,, 4}
at
org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapt
er.java:54)
at
org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSit
e.java:51)
at
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.
java:128)
at
au.com.transentia.utils.test.FastSplitTest.setUp(FastSplitTest.groovy:21)
at
com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl
.java:25)
at
com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)
Process finished with exit code -1
===
I also tried:
===
void setUp() {
def fastSplit = {delim, expected ->
def buffer = []
try {
StringTokenizer st = new StringTokenizer(delegate, delim);
for (int i = 0; i < expected; i++)
buffer[i] = st.nextToken();
return buffer.toArray();
}
catch (NoSuchElementException e) {
throw new NoSuchElementException("Could not successfully split line:
'" + line + "' into " + expected + " items delimited by '" + delim + "'");
}
}
String.metaClass.fastSplit = fastSplit
String.metaClass.fastSplitComma4 = fastSplit.curry(",", 4)
}
===
But...as expected...delegate gets set to FastSplitTest class and so once
gets:
===
groovy.lang.GroovyRuntimeException: Could not find matching constructor for:
java.util.StringTokenizer(au.com.transentia.utils.test.FastSplitTest,
java.lang.String)
at
groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1465)
at
groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1381)
at
org.codehaus.groovy.runtime.callsite.MetaClassConstructorSite.callConstructo
r(MetaClassConstructorSite.java:38)
at
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(Ca
llSiteArray.java:55)
at
org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrap
NoCoerce.callConstructor(ConstructorSite.java:108)
at
org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(Abstra
ctCallSite.java:203)
at
au.com.transentia.utils.test.FastSplitTest$_setUp_closure1.doCall(FastSplitT
est.groovy:26)
[...more elided...]
===
Is there a way of doing what I need here?
Comments/suggestions gratefully received.
Cheers,
BOB
---------------------------------------------------------------------
To unsubscribe from this list, please visit:
http://xircles.codehaus.org/manage_email
I haven't worked out a short way yet but this works:
---------------
String.metaClass.fastSplit = {delim, expected ->
def buffer = []
try {
def tokens = new StringTokenizer(delegate, delim)
for (int i = 0; i < expected; i++) buffer[i] = tokens.nextToken()
buffer.toArray()
}
catch (NoSuchElementException e) {
throw new NoSuchElementException("Could not successfully split line: '$line' into $expected items delimited by '$delim'")
}
}
def c = String.metaClass.methods.find{it.name=='fastSplit'}.closure.curry(",", 4)
String.metaClass.fastSplitComma4 << { c.delegate = delegate; c() }
println "this,is,a,test".fastSplit(",", 4)
println "this,is,a,test".fastSplitComma4()
---------------
We obviously need some clear short way to achieve the equivalent.
Paul.
===============
String.metaClass.fastSplit = {delim, expected ->
def buffer = []
try {
def tokens = new StringTokenizer(delegate, delim)
expected.times{ buffer[it] = tokens.nextToken() }
buffer.toArray()
}
catch (NoSuchElementException) {
def msg = "Could not successfully split line: '$delegate' into $expected items delimited by '$delim'"
throw new NoSuchElementException(msg)
}
}
def c = String.metaClass.methods.find{ it.name=='fastSplit' }.closure.curry(",", 4)
String.metaClass.fastSplitComma4 << { c.delegate = delegate; c() }
println "this,is,a,test".fastSplit(",", 4)
println "this,is,a,test".fastSplitComma4()
================
Paul.
Yet another long version:
:::::::::::::::
String.metaClass.fastSplit = {delim, expected ->
def buffer = []
try {
def tokens = new StringTokenizer(delegate, delim)
expected.times{ buffer[it] = tokens.nextToken() }
buffer.toArray()
}
catch (NoSuchElementException) {
def msg = "Could not split '$delegate' into $expected items delimited by '$delim'"
throw new NoSuchElementException(msg)
}
}
def c = String.metaClass.pickMethod('fastSplit', null).closure.curry(",", 4)
String.metaClass.fastSplitComma4 = { c.delegate = delegate; c() }
println "this,is,a,test".fastSplit(",", 4)
println "this,is,a,test".fastSplitComma4()
:::::::::::::::
Paul.
Oh you show-off (and I mean that in the nicest way :-))! Multiple solutions,
no less...
>
> So, what really is the reason for doing it like
>
> String.metaClass.fastSplitComma4 = { c.delegate = delegate; c() }
I'm with Roshan here: why?
Interestingly (for me), this works without messing with delegates, so the
metaClass stuff is modifying life in some interesting way?:
===
public class Curries {
def spicy = { meat, sauce ->
println "${meat} with ${sauce}"
}
def chickenCurry = spicy.curry('chicken')
def chickenMadras = chickenCurry.curry('madras')
static void main(args) {
new Curries().chickenMadras()
// also OK:
// new Curries().spicy('beef', 'portugese sauce')
}
}
===
I'm also with you:
> We obviously need some clear short way to achieve the
> equivalent.
Cheers,
BOB
> org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(Abstra
> ctCallSite.
> java:128)
> at
>
> au.com.transentia.utils.test.FastSplitTest.setUp(FastSplitTest.gr
> oovy:21)
> at
>
> com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.ja
> va:40)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
>
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorI
> mpl.java:39
> )
> at
>
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodA
> ccessorImpl
> .java:25)
> at
>
> com.intellij.rt.execution.application.AppMain.main(AppMain.java:9
> 0)
>
>
frankly... this looks strange... If all goes right, then c.delegate
should call CurriedClosure.setDelegate which does simply call
setDelegate on the uncurried closure. But the curried closure will
respond to getDelegate with its own delegate, rather then with
owner.delegate.. this sounds like a bug to me
bye blackdrag
--
Jochen "blackdrag" Theodorou
The Groovy Project Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
I suspect a bug too...
Paul.
--
View this message in context: http://www.nabble.com/metaclass-and-curry%28%29-gives-MissingMethodException-tp21199683p21209797.html
Sent from the groovy - user mailing list archive at Nabble.com.
BOB
Thanks for finding/submitting the issue. Should be fixed in svn.
If you get a chance to double check with your examples that would
be great.
Paul.
I was most impressed ;-)
I will give it a try and see what I can see...
Happy new year to you and your family.
Hope the coming year isn't going to be all doom and gloom.
Cheers,
I just tested against
http://bamboo.ci.codehaus.org/download/GROOVY-DEF/artifacts/build-175/Jars/g
roovy-all-1.6-RC-2-SNAPSHOT.jar
All is now OK.
Great work, thank you.
BOB