2

I am learning how to integrate Java library with Ruby code and come to the following question.

I have a command pattern implemented in Java, as follows:

public interface Command {
  public String execute(String param);
}

public class CommandRunner {

  public String run(Command cmd, String param) {
    return cmd.execute(param)+" [this is added by run method]";
  }
}

When I import that to JRuby program I can implement Ruby class that respond_to? :execute with one parameter and pass it to the CommandRunner.new.run. That works and that's clear.

But I can also do this:

def put_through_runner(param, &block)
  CommandRunner.new.run block, param
end

p = put_through_runner "through method" do |param|
  "Cmd implementation in block, param: #{param}"
end

puts p

Instead of passing to Java CommandRunner an object implementing the execute method I pass it a block of code, that does not implement the method. And It works: calls the block as if it was implementation of the execute method! How is that possible? What does JRuby do with the block when passing it to Java? If I had the CommandRunner implemented in Ruby the above code would not work.

3
  • i suspect that something adds an execute method to your proc object. you could check that in your put_through_runner method. Commented Nov 5, 2013 at 15:05
  • Nothing adds the execute method. First: there is nothing that could do it, second: that was the first thing I checked -- in the put_through_runner method the block object does not respond_to? :execute. Commented Nov 6, 2013 at 21:43
  • having respond_to? returning false does not necessary mean that this is actually the case. it depends on the way respond_to? is implemented. Commented Nov 6, 2013 at 21:45

1 Answer 1

3

The reason that this works is a feature called 'closure conversion' (see docs here). What happens is that the block you pass is converted into a Proc object with a proxy that invokes the code in the block for any method that is called on the object.

Sign up to request clarification or add additional context in comments.

1 Comment

Great answer! I'm very grateful. I had not idea where to look for an explanation and how can I exploit this feature. Now that's clear. BTW: very nice feature of JRuby

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.