Today I tried to create an anonymous class from an inteface in JRuby.
After a little bit of experimenting a collegue showed me that I need to alter
the singelton class of an instance of the interface in order to implement a method.
Here I implement the Callable-Interface:
callable = Java::java.util.concurrent.Callable.new class << callable def call # implements method 'call' of the Callable-Interface end end
So I tried this:
require 'java' include_class 'java.util.concurrent.Callable' include_class 'java.util.concurrent.Executors' msg = "from thread" callable = Java::java.util.concurrent.Callable.new class << callable def call msg end end executor_service = Executors.newFixedThreadPool 1 future = executor_service.submit callable puts "hello #{future.get}" # -> undefined local variable or method `msg'
For my suprise, a variable defined in the outer context was invisible for the implemented method. I expected that it would behave just like a Ruby block or a Java anonymous class which can "see" the outer defined variables.
We found a workaround for this problem by calling a method on the instance that initializes a instance variable with the needed object:
require 'java' include_class 'java.util.concurrent.Callable' include_class 'java.util.concurrent.Executors' msg = "from thread" callable = Java::java.util.concurrent.Callable.new class << callable def init(msg) @msg = msg end def call @msg end end callable.init msg executor_service = Executors.newFixedThreadPool 1 future = executor_service.submit callable puts "hello #{future.get}" # -> hello from threadPlease let me know if there a more elegant way to accomplish this!
Using keywords such as `class' and `def' change the current scope - so your `msg' varialbe is no longer local within your #init and #call methods. Said another way: `class' and `def' can't close over outer variables.
ReplyDeleteWhat you wan't is some way to define #init and #call as a closure, which can capture `msg'. For that, you'd wan't to use Module#define_method. For further details, check out my two answers to this StackOverflow question:
http://stackoverflow.com/questions/2495550/define-a-method-that-is-a-closure-in-ruby/2495650#2495650
Cheers,
-Charles
Nice one, ran into the same problem as well with anonymous classes and interfaces. Good reference here too:
ReplyDeleteAnonymous class implements interface
https://www.ruby-forum.com/topic/188599
ReplyDeleteMaybe this link will solve your prob.