|
|||||
|
|||||
method_missing in Jaskell
Method MissingThe Ruby language has a method_missing mechanism for an object to be notified when a method is invoked but not defined by this object. This mechanism can be useful in senarios such as object-relational mapping. Jaskell has support for method_missing too. By default, when an undefined tuple member is referenced, Jaskell runtime throws an exception. This behavior can be customized by providing a custom Resolver implementation to the Jaskell runtime. For example, we could mimic Ruby's method_missing with the following code: MyResolver.java public class MyResolver extends NilResolver{ private static final String trapname = "method_missing"; public Object resolveMember(Object obj, String name, Object def) { final Tuple tuple = DefaultResolver.asTuple(obj); if(tuple==null){ return def; } final TupleMember mbr = tuple.getMember(trapname); if(mbr==null) return def; final Object trap = mbr.eval(tuple); if(trap instanceof Function){ return ((Function)trap).f(name); } else return trap; } } And it can be used as: Jaskell jaskell = Jaskell.defaultInstance() .setResolver(new EitherResolver(DefaultResolver.instance(), new MyResolver())); assertEquals("hello", jaskell.eval("{method_missing name = name}.hello"));
As you can see, the name "method_missing" in Jaskell is not defined by the language. Rather, it is specified by a Resolver implementation. We could, if we want, use "member_not_found", "method_unknown" etc as the special handler method name. In fact, any action can be taken for method_missing, calling a method with a predefined method name is just one strategy among many. This allows us to provide different method_missing mechanisms depending on the problem domain being addressed. Unresolved variablesThe Resolver interface can also be used to resolve variables that're not defined in jaskell script. Typically, when you simply type "a+b" in Jaskell shell, you will get an "variable not resolved" error because variable "a" and "b" are used without definition. This behavior can be customized with a custom Resolver implementation: VarResolver.java public class VarResolver extends DefaultResolver{ private final Map vars; public Object resolveVar(String name, Object def) { final Object r = vars.get(name); if(r==null) return super.resolveVar(name, def); else return r; } public VarResolver(Map vars) { this.vars = vars; } } And it can be used as: HashMap vars = new HashMap(); Jaskell jaskell = Jaskell.defaultInstance() .setResolver(new VarResolver(vars)); vars.put("a", new Integer(1)); vars.put("b", new Integer(2)); assertEquals(new Integer(3), jaskell.eval("a+b")); |
|||||
|
Copyright 2003-2006 - The Codehaus. All rights reserved unless otherwise noted.
Powered by Atlassian Confluence
|
|||||