scriptingContainer callMethod question

I can get scriptingContainer to call methods in my JRuby file but not if
the method is within a class.

For example if the file contains

def onActivityResult(a,b,c)
# do something
end

or an alternative version

def startmeup
tt = Testclass.new
end

class Testclass

def onActivityResult(a,b,c)
      # do something
end

end

The first version that is not in the class works fine but I can’t figure
out how (or if) scriptingContainer can call the method inside the class
in the second version.

Thanks

…R

Please paste your actual scriptingContainer.callMethod(…) invocation.

I don’t know what this is going to achieve - because it works properly
with the first version of my JRuby code and I don’t know how to
configure it for the second version … but here it is (ignore the crude
log messages)

@Override
 public void onActivityResult(int requestCode, int resultCode,

Intent data)
{
Log.e(“SOMETHING”, “here we are in onActivityResult”);
String method = “onActivityResult”;
Object[] args = new Object[3];
args[0] = requestCode;
args[1] = resultCode;
args[2] = data;
Log.e(“SOMETHING”, “here we are 2 onActivityResult”);
container.callMethod(receiver, method, args, Double.class);
}

Do you know if it is possible to use scriptingContainer to call a method
within a class?

…R

Gergely N. wrote in post #1093957:
Please paste your actual scriptingContainer.callMethod(…) invocation.

I don’t know what this is going to achieve

It would just make your question a bit specific, so as to help us answer
it.
Obviously what is interesting is not what variable you pass receiver in,
but what the value is.

As Keith suggests, if the receiver is the result of “Testclass.new” or
“startmeup” then you’re on the right track.

Robin -

How are you getting your receiver object? Here’s an example from an
article at http://java.dzone.com/articles/integrating-jruby-and-java:

Object greeter = container.runScriptlet(“CustomerClassSelector.new”);
String customerClass = container.callMethod(greeter, “choose_class”,
loyaltyPoints, String.class);

  • Keith

Keith R. Bennett

Jeez - I thought this was a simple question…

Yeah, it should have been simple, you just missed 1 simple necessary
detail
to be able to help you (while getting a lot of unnecessary ones).
You found a method wasn’t working, and I was simple asking how you call
that method.

Also, to head off any digression, this is a scriptingContainer question

Action, this question doesn’t seem specific to ScriptingContainer or
even JRuby (or Android, as you said). It’s more about “how to instance
method in Ruby?”

Therefore the best is to understand a bit more of Ruby object model, eg
see
Programming Ruby: The Pragmatic Programmer's Guide.

So the simple answer to your simple question would be “to be able to
call a
method, first you need an object for it that can handle it”. I assume
that
would not make you happier, so I’ll try to clarify further.

The idea is to send a message to the receiver, where receiver is an
object which knows how to handle it and respond (in the lucky case).
What messages an object can handle depends on the methods defined in
its class (there’s more to that, but let’s keep it simple now).
You create an object of a class named CustomerClassSelector, by calling
.new method on the class (to answer your other question).

In your first attempt, you just defined a method on the class named
“Object” (the default place for top-level method).
Since this is the root of the class hierarchy all objects will have your
method.
IOW it does not matter what the receiver object is in your first case,
hence it works.

In your second one, you’re defining the method within a TestClass, so it
will be only available in objects of TestClass.
That’s why we were asking what your receiver object is.

I use the same receiver in the second method onActivityResult()

This is probably wrong, if I understand your snippets your receiver
object
is not a TestClass -in fact it’s probably a nil (which is an object of
NilClass).

Again, what you probably should do is the set the receiver there to the
result of “startmeup” , in this case the result of the first callMethod.
In pure Ruby, this would be
mytest = startmeup()
mytest.onActivityResult(…)

hope this helps,
Gergo

Thanks Gergo, that has enabled me to get it working.

In the first method I now have

receiver = container.runScriptlet(PathType.CLASSPATH, filename)
String method = “startMeUp”;
theClass = container.callMethod(receiver, method, Object.class);

and in the JRuby code the method “startMeUp” returns the class instance
it has created

and in the second method I have

container.callMethod(theClass, method, args, Double.class);

Gergely N. wrote in post #1094052:

Jeez - I thought this was a simple question…

Yeah, it should have been simple, you just missed 1 simple necessary
detail
to be able to help you (while getting a lot of unnecessary ones).
You found a method wasn’t working, and I was simple asking how you call
that method.

No, I had no non-working method because I didn’t even know how to get
that far when the JRuby method was in a class.

Also, to head off any digression, this is a scriptingContainer question

Action, this question doesn’t seem specific to ScriptingContainer or
even JRuby (or Android, as you said). It’s more about “how to instance
method in Ruby?”

The solution has shown that this was completely a ScriptingContainer
question - none of the documentation I have read has even hinted that
ScriptingContainer can be used like this. What other useful secrets has
it got?

Therefore the best is to understand a bit more of Ruby object model, eg
see
Programming Ruby: The Pragmatic Programmer's Guide.

So the simple answer to your simple question would be “to be able to
call a
method, first you need an object for it that can handle it”. I assume
that
would not make you happier, so I’ll try to clarify further.

The idea is to send a message to the receiver, where receiver is an
object which knows how to handle it and respond (in the lucky case).
What messages an object can handle depends on the methods defined in
its class (there’s more to that, but let’s keep it simple now).
You create an object of a class named CustomerClassSelector, by calling
.new method on the class (to answer your other question).

Yes, I already knew this as it applied to regular JRuby.

In your first attempt, you just defined a method on the class named
“Object” (the default place for top-level method).
Since this is the root of the class hierarchy all objects will have your
method.
IOW it does not matter what the receiver object is in your first case,
hence it works.

In your second one, you’re defining the method within a TestClass, so it
will be only available in objects of TestClass.
That’s why we were asking what your receiver object is.

I understand now, but I would have liked it if you had explained your
question.

I use the same receiver in the second method onActivityResult()

This is probably wrong, if I understand your snippets your receiver
object
is not a TestClass -in fact it’s probably a nil (which is an object of
NilClass).

Again, what you probably should do is the set the receiver there to the
result of “startmeup” , in this case the result of the first callMethod.
In pure Ruby, this would be
mytest = startmeup()
mytest.onActivityResult(…)

hope this helps,

Yes it has, thanks again

Gergo

Thanks Keith and Gergely,

Jeez - I thought this was a simple question…

At the moment I have two methods in my Java code (it’s for an Android
device). With onCreate() I start the script with

receiver = container.runScriptlet(PathType.CLASSPATH, filename)
String method = “startMeUp”;
container.callMethod(receiver, method);

“filename” is the name of my JRuby file.

then I use the same receiver in the second method onActivityResult() but
changing the name of the JRuby method to be called.

As I said in my original post this all works fine as long as the methods
in the JRuby file aren’t enclosed in a class - and I can live with that
if that’s the way things must be.

I have tried a version of my code in which all but the “startmeup”
method is enclosed in a class and “startmeup” includes the code

@jj = Myclass.new
@jj.setup

Then I would like to be able to call directly from Java into the class

@jj.onActivityResult(a,b,c)

I’m afraid I can’t figure out your example and the link is broken.

First, is “CustomerClassSelector” the name of a variable from somewhere
else or is it an indicator of something I should replace with my own
variable, and if so what sort of thing would it be?

Second, what does the “.new” part of CustomerClassSelector do? and where
does it do it? If it is an initialize of a JRuby class does this mean
that the class is initialized every time the scriplet is run, and if so
how do you maintain JRuby instance variable between calls.

Perhaps I should make it clear that the calls to JRuby are NOT for the
purpose of returning info to the Java program. I want everything to
happen in JRuby and the Java is just an unavoidable irritant to pick up
Android callbacks and pass them on to JRuby and I want to minimize the
Java.

Also, to head off any digression, this is a scriptingContainer question,
not an Android question. If someone can explain how to do what I want
with regular Java I can check if it works on Android.

Again, Thanks

…R

Keith B. wrote in post #1093974:
Robin -

How are you getting your receiver object? Here’s an example from an
article at http://java.dzone.com/articles/integrating-jruby-and-java:

Object greeter = container.runScriptlet(“CustomerClassSelector.new”);
String customerClass = container.callMethod(greeter, “choose_class”,
loyaltyPoints, String.class);

  • Keith

Keith R. Bennett
Keith R. Bennett - Reston, Virginia, Bennett Business Solutions Inc | about.me