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 thread
Please let me know if there a more elegant way to accomplish this!

