Tapping into Ruby from the JVM

ruby on tap

Concise, tight logic

if options.fetch :squash, true
  result.shift && @lineno += 1 while (top = result[0]) && top.empty?
  result.pop while (bot = result[-1]) && bot.empty?
end

DSLs FTW!

block {
  named :shout
  on_context :paragraph
  parse_content_as :simple
  name_attributes 'vol'
  process &-> (parent, reader, attrs) {
    volume = ((attrs.delete 'vol') || 1).to_i
    create_paragraph parent, (reader.lines.map {|line|
        line.upcase.gsub /\.(?= |$)/, '!' * volume }), attrs
  }
}
ruby on tap

JVM, at your service

What’s JRuby?

JIT in Action

$HOME/.jrubyrc
jit.threshold=10
jit.logging=true
$ jruby -J-server bench.rb
JITCompiler: done jitting:Asciidoctor::Parser.store_attribute
    at ...lib/asciidoctor/parser.rb:2084
JITCompiler: done jitting:Asciidoctor::Parser.sanitize_attribute_name
    at ...lib/asciidoctor/parser.rb:2679

Shout out to JRuby, powering most of Travis CI for the better of three years now!

— Mathias Meyer (@roidrage) April 26, 2014

JRuby: 2 ways

keep calm use jruby jruby colors
asciidoctor java integration
build plugins
room views
java ruby interop
dual citizenship passports
redbridge
Ruby Red Bridge

Running Ruby inside Java

import org.jruby.embed.ScriptingContainer;
...
ScriptingContainer container = new ScriptingContainer();
container.runScriptlet("puts 'Hello from Ruby!'");
Hello from Ruby!

Feeding the Engine

Passing Data to Ruby

ScriptingContainer container = new ScriptingContainer();
container.put("message", "Hello from Ruby!");
container.runScriptlet("puts message");
Hello from Ruby!

Returning Data from Ruby

ScriptingContainer container = new ScriptingContainer();
container.put("message", "Hello from Java with help from Ruby!");
IRubyObject result = container.runScriptlet("message.upcase");
System.out.println(result);
HELLO FROM JAVA WITH HELP FROM RUBY!
wooden duck 2

“Wooden Duck Typing”

ScriptingContainer container = new ScriptingContainer();
Ruby runtime = container.getProvider().getRuntime();
String script = "require 'asciidoctor'\nAsciidoctor"
IRubyObject result = (IRubyObject) container.runScriptlet(script);
Asciidoctor asciidoctor = JavaEmbedUtils
    .rubyToJava(runtime, result, Asciidoctor.class);
String html = asciidoctor.convert_file("sample.adoc");
wolf sheep 16 9
giving tree quilt

Where the Gems At?

Loading from a JAR

gems.jar
gems/
  specifications/
    asciidoctor-1.5.0.gemspec
  gems/
    asciidoctor-1.5.0/
      lib/
        asciidoctor.rb
        asciidoctor/
container.runScriptlet("require 'asciidoctor'")

Herding JRuby

Installing JRuby using RVM

$ \curl -sSL "https://get.rvm.io" > rvm-install.sh
  bash rvm-install.sh -s latest
  rvm install jruby
  rvm use jruby
  jruby --version
jruby 1.7.13 (1.9.3p392) 2014-06-24 43f133c

rvm-logo

Packaging & Deployment

Distribution

gems via maven

Tricky Bits

JRuby 9000 is starting to shape up. Finishing Ruby 2.1 features, wiring up the new JIT, big overhaul of encodings and IO. Preview soonish.

— Charles Nutter (@headius) July 6, 2014

Truffle: JRuby, 28x as fast!

keep calm use jruby jruby colors

Thanks!