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!