https://github.com/headius/invokebinder/
I've finished mapping MethodHandles.* and Lookup.* to its API, and
have also added a couple convenience utilities like tryFinally and nop
that are hard or confusing to implement with the MethodHandles API.
I'm interested in incorporating other utilities and patterns that you
might have...feel free to submit a pull request.
Not released to Maven yet, but will be soon as 1.0.
BinderTest (https://github.com/headius/invokebinder/blob/master/src/test/java/com/headius/invoke/binder/BinderTest.java)
has several good examples but I'm particularly proud of tryFinally:
MethodHandle post = Binder
.from(void.class, String[].class)
.invokeStatic(MethodHandles.lookup(),
BinderTest.class, "finallyLogic");
MethodHandle handle = Binder
.from(void.class, String[].class)
.tryFinally(post)
.invokeStatic(MethodHandles.lookup(),
BinderTest.class, "setZeroToFoo");
Which is implemented as follows:
MethodHandle exceptionHandler = Binder
.from(target.type().insertParameterTypes(0,
Throwable.class).changeReturnType(void.class))
.drop(0)
.invoke(post);
MethodHandle rethrow = Binder
.from(target.type().insertParameterTypes(0, Throwable.class))
.fold(exceptionHandler)
.drop(1, target.type().parameterCount())
.throwException();
target = MethodHandles.catchException(target, Throwable.class, rethrow);
// if target returns a value, we must return it regardless of post
MethodHandle realPost = post;
if (target.type().returnType() != void.class) {
// modify post to ignore return value
MethodHandle newPost = Binder
.from(target.type().insertParameterTypes(0,
target.type().returnType()).changeReturnType(void.class))
.drop(0)
.invoke(post);
// fold post into an identity chain that only returns the value
realPost = Binder
.from(target.type().insertParameterTypes(0,
target.type().returnType()))
.fold(newPost)
.drop(1, target.type().parameterCount())
.identity();
}
return MethodHandles.foldArguments(realPost, target);
Which would be quite a bit more code (and more confusing) using the
MethodHandles API directly.
- Charlie
In general I have till now a bit a problem of keeping the numbers of
method handles low. If I for example have to bind multiple values at
different places in my code, this usually turns out to be multiple
insertArguments calls, each of them producing new method handles. I am
wondering how to avoid that problem
bye Jochen
--
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org