On 2/20/07, Michael <[EMAIL PROTECTED]> wrote:
How would the RubyObjectWrapper work when specifying method argument,
e.g$jrubyObject.testMethod( "argument1", "argument2" ) ?
hmm. right now, i see only a few options:
a) the wrapper knows what methods it's wrapped object has and
re-implements them itself:
public Object testMethod(String a, String b) {
return new RubyObjectWrapper(this.foo.callMethod(
this.foo.getRuntime(), "testMethod", new String[] { a, b }));
}
Obviously that means a lot more work on your part and a lot less
flexibility. But, if you have consistent methods, it may be worth it
for a few of them.
b) you give up the $jrubyObject.testMethod("arg1", "arg2") syntax and
try to find another that's bearable, like
$jrubyObject.call('testMethod', ["arg1", "arg2"])
public class RubyObjectWrapper {
private RubyObject foo;
public RubyObjectWrapper(RubyObject wrapMe) {
this.foo = wrapMe;
}
public Object get(String methodName) {
Object result = this.foo.callMethod(foo.getRuntime(), methodName);
return new RubyObjectWrapper(result);
}
public Object call(String methodName, List args) {
Object result = this.foo.callMethod(foo.getRuntime(),
methodName, args.toArray());
return new RubyObjectWrapper(result);
}
}
c) again, give up the $jrubyObject.testMethod("arg1", "arg2") syntax
and design the wrapper to allow a more natural-language-like interface
such as
$jrubyObject.testMethod.with("arg1").and("arg2")
this could be done with a wrapper class like:
public class RubyObjectWrapper {
private RubyObject foo;
public RubyObjectWrapper(RubyObject wrapMe, List args) {
this.foo = wrapMe;
}
public Object get(String methodName) {
return new Builder(methodName, new ArrayList());
}
public Object call(String methodName, List args) {
Object result = foo.callMethod(foo.getRuntime(), methodName,
args.toArray());
return new RubyObjectWrapper(result);
}
public String toString() {
return this.foo.toString();
}
public class Builder {
private String method;
private List args;
public Builder(String method, List args) {
this.method = method;
this.args = args;
}
public Object with(String arg) {
this.args.add(arg);
}
/* just to be fancy... */
public Object and(String arg) {
this.args.add(arg);
}
public Object call() {
return RubyObjectWrapper.this.call(method, args);
}
public String toString() {
return call().toString();
}
}
}
...or something like that.
I already start down the road of using an Event handler for InvalidReference
to catch instances of RubyObject. It works for $jrubyObject.testMethod , but
I am having the same problem as above, how to handle method arguments? The
InvalidReferenceEventHandler#invalidMethod does not appear to contain the
argument information for a reference $jrubyObject.testMethod( "argument1",
"argument2" )
Perhaps someone else knows a way to get the arg information, but as it
is, i make precious little use of event handlers and don't know. i
might dig around and see what i can find though.
thanks,
Michael
On 2/20/07, Nathan Bubna <[EMAIL PROTECTED]> wrote:
>
> I imagine you could get pretty far by wrapping the RubyObjects in a
> more Velocity-friendly object that takes advantage how Velocity treats
> get(String) methods before putting it into the context.
>
> Perhaps something like:
>
>
> public class RubyObjectWrapper {
> private RubyObject foo;
> public RubyObjectWrapper(RubyObject wrapMe) {
> this.foo = wrapMe;
> }
> public Object get(String methodName) {
> return new RubyObjectWrapper(this.foo.callMethod(
> foo.getRuntime(), methodName));
> }
> }
>
> If i understand the problem space here, this should allow you to
> traverse the object graph for you RubyObjects as you ask:
>
> $jrubyObject.testMethod
>
> I'm really not at all familiar with Ruby, much less JRuby, but perhaps
> this will help you get on the right track. I use tricks like this to
> simplify the VTL syntax for various tools in VelocityTools all the
> time.
>
> The other thing which may help here is using Velocity's EventHandler
> capabilities to recognize when a reference is a RubyObject and treat
> it differently. Will is much more experienced and knowledgeable on
> event handlers than i am, so he may be able to tell you better whether
> or not that is a dead end for this sort of thing.
>
>
> On 2/20/07, Michael <[EMAIL PROTECTED]> wrote:
> > Hello,
> >
> > I have been using Velocity for years now and find it the best templating
> > language around. This has lead me to try and spread the joy by
> attempting to
> > swap out RHTML for Velocity in JRuby on Rails.
> >
> > I have a few simple Ruby test scripts that parse a templates Velocity.
> > Things get messy when Velocity needs to traverse an object graph. When
> used
> > in Rails, the VelocityContext can have a mix of Java objects and
> RubyObject
> > (these are the problematic ones). The RubyObject is a wrapper for a
> Ruby
> > object from the JRuby runtime. The RubyObjects do not have static typed
> > methods, but everything must go through the method 'callMethod'.
> >
> > For example, to use velocity notation on the Java object 'sample' to get
> the
> > method 'test':
> > $sample.test
> >
> > would be on a RubyObject 'sample' to get the method 'test':
> > $sample.callMethod( $sample.getRuntime(), "test" )
> >
> > Things get sticker for passing arguments to a method in RubyObject, all
> > arguments must implement IRubyObject. I will just skip over this for
> now.
> >
> > Here is the crux of my question, is it possible to extend Velocity to
> add
> > support for handling RubyObjects? Ideally Velocity would be able to
> > determine whether an object is an implementation of RubyObject, or not,
> and
> > handle appropriately, i.e $jrubyObject.testMethod could be call directly
> > instead of the callMethod for a RubyObject.
> >
> >
> > thanks,
> > Michael
> > [EMAIL PROTECTED]
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]