SlideShare une entreprise Scribd logo
1  sur  110
Télécharger pour lire hors ligne
JRuby:
 Enhancing Java Developers' Lives
 Hiro Asari
 @hiro_asari
 JRuby Support Engineer
 Engine Yard
 @engineyard
Wednesday, November 16, 11
JRuby: a Brief
                                       History
                             Where it came from, and where it is now




Wednesday, November 16, 11
History
   • September 10, 2001
   Source:(Wikipedia




Wednesday, November 16, 11
History




Wednesday, November 16, 11
History
   • 10+ years old
   • Led by Charles Nutter and
     Tom Enebo
   • 14.800+ commits




Wednesday, November 16, 11
Project Status
   • Current Stable Release:
     1.6.5
   • Compatible with Ruby
     1.8.7 and 1.9.2
   • Supports Rails 3.1




Wednesday, November 16, 11
Getting JRuby

   h0p://jruby.org/download




Wednesday, November 16, 11
Trying JRuby
   h0p://jruby.org/tryjruby




Wednesday, November 16, 11
Book




Wednesday, November 16, 11
Quick Tour of
                                     Ruby
                             A brief overview of the language




Wednesday, November 16, 11
Classes

   public class Circle extends Shape {        class Circle < Shape
     private final int radius;                  def initialize(radius)
                                                  @radius = radius
       public Circle(int radius) {              end
         this.radius = radius;
       }                                         attr_reader :radius
       public int getRadius() {
         return radius;                          def area
       }                                           Math::PI*(@radius **
       public double getArea() {              2)
         return Math.PI * Math.pow(radius,2);    end
       }                                      end
       public static void main(String[] a) {
         double area=new Circle(2).getArea(); puts Circle.new(2).area
         System.out.println(area);
       }
   }



Wednesday, November 16, 11
Single Inheritance
                                       Same Thing
   public class Circle extends Shape {        class Circle < Shape
     private final int radius;                  def initialize(radius)
                                                  @radius = radius
       public Circle(int radius) {              end
         this.radius = radius;
       }                                         attr_reader :radius
       public int getRadius() {
         return radius;                          def area
       }                                           Math::PI*(@radius **
       public double getArea() {              2)
         return Math.PI * Math.pow(radius,2);    end
       }                                      end
       public static void main(String[] a) {
         double area=new Circle(2).getArea(); puts Circle.new(2).area
         System.out.println(area);
       }
   }



Wednesday, November 16, 11
Constructor

   public class Circle extends Shape {        class Circle < Shape
     private final int radius;                  def initialize(radius)
                                                  @radius = radius
       public Circle(int radius) {              end
         this.radius = radius;
       }                                         attr_reader :radius
       public int getRadius() {
         return radius;                          def area
       }                                           Math::PI*(@radius **
       public double getArea() {              2)
         return Math.PI * Math.pow(radius,2);    end
       }                                      end
       public static void main(String[] a) {
         double area=new Circle(2).getArea(); puts Circle.new(2).area
         System.out.println(area);
       }
   }



Wednesday, November 16, 11
No Type Declarations

   public class Circle extends Shape {        class Circle < Shape
     private final int radius;                  def initialize(radius)
                                                  @radius = radius
       public Circle(int radius) {              end
         this.radius = radius;
       }                                         attr_reader :radius
       public int getRadius() {
         return radius;                          def area
       }                                           Math::PI*(@radius **
       public double getArea() {              2)
         return Math.PI * Math.pow(radius,2);    end
       }                                      end
       public static void main(String[] a) {
         double area=new Circle(2).getArea(); puts Circle.new(2).area
         System.out.println(area);
       }
   }



Wednesday, November 16, 11
Instance Variables
                             ‘@’ == ‘this.’ and is mandatory
   public class Circle extends Shape {            class Circle < Shape
     private final int radius;                      def initialize(radius)
                                                      @radius = radius
       public Circle(int radius) {                  end
         this.radius = radius;
       }                                         attr_reader :radius
       public int getRadius() {
         return radius;                          def area
       }                                           Math::PI*(@radius **
       public double getArea() {              2)
         return Math.PI * Math.pow(radius,2);    end
       }                                      end
       public static void main(String[] a) {
         double area=new Circle(2).getArea(); puts Circle.new(2).area
         System.out.println(area);
       }
   }



Wednesday, November 16, 11
Working with Instance Variables
                             Common tasks are easy
   public class Circle extends Shape {        class Circle < Shape
     private final int radius;                  def initialize(radius)
                                                  @radius = radius
       public Circle(int radius) {              end
         this.radius = radius;
       }                                         attr_reader :radius
       public int getRadius() {
         return radius;                          def area
       }                                           Math::PI*(@radius **
       public double getArea() {              2)
         return Math.PI * Math.pow(radius,2);    end
       }                                      end
       public static void main(String[] a) {
         double area=new Circle(2).getArea(); puts Circle.new(2).area
         System.out.println(area);
       }
   }



Wednesday, November 16, 11
Symbols
    :identifier




   • Prefixed with a colon
   • Uniquely defined in a runtime




Wednesday, November 16, 11
Point of No Return
                             Last Expression is always return value
   public class Circle extends Shape {               class Circle < Shape
     private final int radius;                         def initialize(radius)
                                                         @radius = radius
       public Circle(int radius) {                     end
         this.radius = radius;
       }                                         attr_reader :radius
       public int getRadius() {
         return radius;                          def area
       }                                           Math::PI*(@radius **
       public double getArea() {              2)
         return Math.PI * Math.pow(radius,2);    end
       }                                      end
       public static void main(String[] a) {
         double area=new Circle(2).getArea(); puts Circle.new(2).area
         System.out.println(area);
       }
   }



Wednesday, November 16, 11
.new is just a class method

   public class Circle extends Shape {        class Circle < Shape
     private final int radius;                  def initialize(radius)
                                                  @radius = radius
       public Circle(int radius) {              end
         this.radius = radius;
       }                                         attr_reader :radius
       public int getRadius() {
         return radius;                          def area
       }                                           Math::PI*(@radius **
       public double getArea() {              2)
         return Math.PI * Math.pow(radius,2);    end
       }                                      end
       public static void main(String[] a) {
         double area=new Circle(2).getArea(); puts Circle.new(2).area
         System.out.println(area);
       }
   }



Wednesday, November 16, 11
Blocks/Closures
   • Pass an anonymous function to a method call
   # Look mom...no boilerplate!
   my_open(file) do |io|          letters.group_by {|b| b.zip_code }
     first_line = io.gets
     # ...
   end

   def my_open(file, mode='r')
     io = File.open(file)
     yield io                     button.action_performed do
   ensure                           exit
     io.close                     end
   end




Wednesday, November 16, 11
Modules
 module Enumerable                            class MyTree
   def find(if_none = nil)                      include Enumerable
     each { |o| return o if yield(o) }
     if_none                                    # tree impl not shown :)
   end
                                                def each
      # Many other methods not shown              # yield each element
                                                  # in tree
   def collect                                  end
     ary = []                                 end
     each { |o| ary << yield(o) }
     ary
   end
 end


              dude = people.find { |person| person.id == 123 }

              floats = [1,2].collect { |int| int.to_f } # => [1.0, 2.0]


Wednesday, November 16, 11
Everything is an Expression


  class Color
    COLORS = {:red => 0xff0000, :green => 0x00ff00, :blue => 0x0000ff}

    COLORS.each do |name, value|
       define_method(name) do
        value
      end
    end
  end




Wednesday, November 16, 11
Classes/Modules are open

     class MyTree
       def each
         #...
       end
     end

     #... later in source
     #... maybe even different file

     class MyTree
       def debug
         #...
       end
     end




Wednesday, November 16, 11
Pure OO Language
   • Everything is an object
     MyTree.foo #=> method call
     12 + 8 #=> here, '+' is a method on Fixnum, 12.
     12.to_s(8) #=> "14"
     puts 11.odd? #=> true




Wednesday, November 16, 11
JRuby on Rails
                                    Ruby's Killer app




Wednesday, November 16, 11
Java Web Frameworks


                             Devoxx 2010




Wednesday, November 16, 11
Java Web Frameworks
                         h0p://j.mp/raible<jvm<frameworks


                               COMPARING JVM WEB
                                  FRAMEWORKS
                                                 Matt Raible
                                           http://raibledesigns.com




                                 Images by Stuck in Customs - http://www.flickr.com/photos/stuckincustoms
                                                                                                           © 2010, Raible Designs
                                                            © 2010 Raible Designs




Wednesday, November 16, 11
Install Rails
     $ jruby -S gem install rails
     Fetching: multi_json-1.0.3.gem (100%)
     ⋮
     Fetching: bundler-1.0.21.gem (100%)
     Fetching: rails-3.1.1.gem (100%)
     Successfully installed multi_json-1.0.3
     Successfully installed activesupport-3.1.1
     ⋮
     Successfully installed thor-0.14.6
     Successfully installed rack-ssl-1.3.2
     Successfully installed json-1.6.1-java
     Successfully installed rdoc-3.11
     Successfully installed railties-3.1.1
     Successfully installed bundler-1.0.21
     Successfully installed rails-3.1.1
     31 gems installed




Wednesday, November 16, 11
Generate Rails app
     $ jruby -S rails new awesomeapp
           create
     ⋮
           create vendor/plugins
           create vendor/plugins/.gitkeep
              run bundle install
     Fetching source index for http://rubygems.org/
     Using rake (0.9.2.2)
     ⋮
     Using json (1.6.1)
     Using rdoc (3.11)
     Using thor (0.14.6)
     Using railties (3.1.1)
     Installing coffee-rails (3.1.1)
     Installing jquery-rails (1.0.16)
     Installing jruby-openssl (0.7.4)
     Using rails (3.1.1)
     Installing sass (3.1.10)
     Installing sass-rails (3.1.4)
     Installing uglifier (1.0.4)
     Your bundle is complete! Use `bundle show [gemname]` to see
       where a bundled gem is installed.

Wednesday, November 16, 11
Rails Scaffolding
     $ jruby -S rails generate scaffold person name:string
     email:string
           invoke active_record
           create    db/migrate/20111107052142_create_people.rb
           create    app/models/person.rb
     ⋮
           create      app/views/people/show.html.erb
           create      app/views/people/new.html.erb
           create      app/views/people/_form.html.erb
           invoke    test_unit
           create      test/functional/people_controller_test.rb
           invoke    helper
           create      app/helpers/people_helper.rb
           invoke      test_unit
           create         test/unit/helpers/people_helper_test.rb
           invoke assets
           invoke    coffee
           create      app/assets/javascripts/people.js.coffee
           invoke    scss
           create      app/assets/stylesheets/people.css.scss
           invoke scss
           create    app/assets/stylesheets/scaffolds.css.scss

Wednesday, November 16, 11
Migrate Database
     $ jruby -S rake db:migrate
     == CreatePeople: migrating ====================================
     -- create_table(:people)
        -> 0.0040s
        -> 0 rows
     == CreatePeople: migrated (0.0040s) ===========================




Wednesday, November 16, 11
Start Server
     $ jruby -S rails server
     => Booting WEBrick
     => Rails 3.1.1 application starting in development on http://
     0.0.0.0:3000
     => Call with -d to detach
     => Ctrl-C to shutdown server
     [2011-11-07 00:26:30] INFO WEBrick 1.3.1
     [2011-11-07 00:26:30] INFO ruby 1.8.7 (2011-11-05) [java]
     [2011-11-07 00:26:30] INFO WEBrick::HTTPServer#start: pid=40454
     port=3000




Wednesday, November 16, 11
First Page




Wednesday, November 16, 11
app/controllers/people_controller.rb
     class PeopleController < ApplicationController
       # GET /people
       # GET /people.json
       def index
         @people = Person.all

           respond_to do |format|
             format.html # index.html.erb
             format.json { render :json => @people }
           end
         end
     ⋮
     end




Wednesday, November 16, 11
JSON out of the box




Wednesday, November 16, 11
app/models/person.rb
     class Person < ActiveRecord::Base
     end




Wednesday, November 16, 11
Rails Deployment




Wednesday, November 16, 11
Rails IDE and text editors




                             jetbrains.com/ruby/


   redcareditor.com                                   netbeans.org

                                                   •emacs
                                                   •vi(m)
                                                   •TextMate
Wednesday, November 16, 11
JRuby in Java web app
                                        Requests


                                              JRuby

            /                /vets   /rack/   Java/
                                              Spring

        App
Wednesday, November 16, 11
JRuby in Java web app
    diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
    index 8d02684..60ed6cb 100644
    --- a/src/main/webapp/WEB-INF/web.xml
    +++ b/src/main/webapp/WEB-INF/web.xml
    @@ -87,6 +87,21 @@
            <listener>
                    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
            </listener>
    +
    +        <listener>
    +                <listener-class>org.jruby.rack.RackServletContextListener</listener-class>
    +        </listener>
    +
    +        <servlet>
    +                <servlet-name>rack</servlet-name>
    +                <servlet-class>org.jruby.rack.RackServlet</servlet-class>
    +        </servlet>
    +
    +        <servlet-mapping>
    +                <servlet-name>rack</servlet-name>
    +                <url-pattern>/rack/*</url-pattern>
    +        </servlet-mapping>
    +

               <!--
                             Defines the 'default' servlet (usually for service static resources).




Wednesday, November 16, 11
Rails in Java web app
                                               Requests



          /                  /vets                       JRuby

                                               /owners   Java/
          /                  /vets   /owners   /1/pets   Spring


        App
Wednesday, November 16, 11
Rails in Java web app
    diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
    index 60ed6cb..f64b34d 100644
    --- a/src/main/webapp/WEB-INF/web.xml
    +++ b/src/main/webapp/WEB-INF/web.xml
    @@ -92,16 +92,6 @@
                     <listener-class>org.jruby.rack.RackServletContextListener</listener-class>
             </listener>

    -           <servlet>
    -                   <servlet-name>rack</servlet-name>
    -                   <servlet-class>org.jruby.rack.RackServlet</servlet-class>
    -           </servlet>
    -
    -           <servlet-mapping>
    -                   <servlet-name>rack</servlet-name>
    -                   <url-pattern>/rack/*</url-pattern>
    -           </servlet-mapping>
    -

               <!--
                    Defines the 'default' servlet (usually for service static resources).
    @@ -162,6 +152,16 @@
                    <url-pattern>/</url-pattern>
            </servlet-mapping>

    +           <filter>
    +                   <filter-name>RackFilter</filter-name>
    +                   <filter-class>org.jruby.rack.RubyFirstRackFilter</filter-class>
    +           </filter>
    +
    +           <filter-mapping>
    +                   <filter-name>RackFilter</filter-name>
    +                   <url-pattern>/*</url-pattern>
    +           </filter-mapping>
    +
               <filter>
                          <filter-name>httpMethodFilter</filter-name>
                          <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>

Wednesday, November 16, 11
More…




       h0p://bit.ly/refactoring<to<rails
        h0p://vimeo.com/25410705


Wednesday, November 16, 11
Testing Libraries
                                   Test-Driven Development




Wednesday, November 16, 11
Testing
              Number of Tests Written (1000's)

                                                 100

                                                  75

                                                  50

                                                  25



                                                       Easy                      Hard
                                                              Ease of Writing Tests
Wednesday, November 16, 11
Test files
     $ jruby -S rails g scaffold person name:string email:string
           invoke active_record
           create    db/migrate/20111107052142_create_people.rb
           create    app/models/person.rb
     ⋮
           create      app/views/people/show.html.erb
           create      app/views/people/new.html.erb
           create      app/views/people/_form.html.erb
           invoke    test_unit
           create      test/functional/people_controller_test.rb
           invoke    helper
           create      app/helpers/people_helper.rb
           invoke      test_unit
           create         test/unit/helpers/people_helper_test.rb
           invoke assets
           invoke    coffee
           create      app/assets/javascripts/people.js.coffee
           invoke    scss
           create      app/assets/stylesheets/people.css.scss
           invoke scss
           create    app/assets/stylesheets/scaffolds.css.scss


Wednesday, November 16, 11
DeepThought.java
    class DeepThought {
        public static int answerToEverything(Object obj) {
            return 42;
        }

             public static String getName() {
                 return "DeepThought";
             }
    }




Wednesday, November 16, 11
RSpec
     require 'rspec'
     require 'java'

     java_import 'DeepThought'

     describe 'DeepThought' do
      describe '.answerToEverything' do
         it "should return 42, given any input" do
           DeepThought.answerToEverything(nil).should == 42
           DeepThought.answerToEverything(true).should == 42
         end
       end

      describe '.getName' do
         it "should return 'DeepThought'" do
           DeepThought.name.should == "DeepThought"
         end
       end
     end




Wednesday, November 16, 11
RSpec
     $ javac DeepThrought.java

     $ jruby -rubygems deep_thought_spec.rb
     ..

     Finished in 0.013 seconds
     2 examples, 0 failures




Wednesday, November 16, 11
Cucumber
     Feature: AnswerToEverything
       Ask DeepThought the answer to everything

         Scenario: Ask a question
           Given nil as input
           Then the result should be 42


     Feature: getName
       Ask DeepThought what its name is

         Scenario: get name
           When asked the name
           Then it answers the name as "DeepThought"




Wednesday, November 16, 11
Cucumber
     $ jruby -S cucumber
     Feature: AnswerToEverything
       Ask DeepThought the answer to everything

         Scenario: Ask a question       # features/answer.feature:4
           Given nil as input           # features/step_definitions…
           Then the result should be 42 # features/step_definitions…

     Feature: getName
       Ask DeepThought what its name is

         Scenario: get name                          # features/…
           When asked the name                       # features/…
           Then it answers the name as "DeepThought" # features/…

     2 scenarios (2 passed)
     4 steps (4 passed)
     0m0.065s




Wednesday, November 16, 11
JTestr
   • Bridge for Java to make use of Ruby testing
   • Integrates with both Ant and Maven
   • Allows mocking of non-final Java class/method
   • Written by Ola Bini




Wednesday, November 16, 11
JTestr Example
    my_project/
       build.xml!
       test/
          test_hashmap.rb
          hashmap_spec.rb
       lib/
          jtestr.jar
       src/
          <your source ;) >




Wednesday, November 16, 11
JTestr in Ant
    <?xml version="1.0" encoding="UTF-8"?>

    <project basedir="." default="jar" name="JRuby">
      <target name="test" description="Runs all tests">
        <taskdef name="jtestr"
                  classname="org.jtestr.ant.JtestRAntRunner"
                  classpath="lib/jtestr.jar"/>
        <jtestr/>
      </target>
    </project>




Wednesday, November 16, 11
Ruby’s test/unit
                               test/test_hashmap.rb


  class HashMapTests < Test::Unit::TestCase
    def setup
      @map = java.util.HashMap.new
    end

       def test_that_an_entry_can_be_added
         @map.put "foo", "bar"
         assert_equal "bar", @map.get("foo")
       end

    def test_empty_key_set_iterator_throws_exception
      assert_raises(java.util.NoSuchElementException) do
        @map.key_set.iterator.next
      end
    end
  end




Wednesday, November 16, 11
RSpec revisited
                              test/hashmap_spec.rb
   require 'java'
  java_import java.util.HashMap

  describe "An empty", HashMap do
    before :each do
      @hash_map = java.util.HashMap.new
    end

       it "should be able to add an entry to it" do
         @hash_map.put "foo", "bar"
         @hash_map.get("foo").should == "bar"
       end

       it "should not be empty after an entry has been added to it" do
         @hash_map.put "foo", "bar"
         @hash_map.should_not be_empty
       end

     it "should be empty" do
       @hash_map.should be_empty
     end
   end
Wednesday, November 16, 11
Results
    $ ant test
    Buildfile: /Users/asari/Development/projects/jtestr-example/
    build.xml

    test:
       [jtestr] Other TestUnit: 2 tests, 0 failures, 0 errors
       [jtestr]
       [jtestr] Other Spec: 3 examples, 0 failures, 0 errors
       [jtestr]
       [jtestr] Total: 5 tests, 0 failures, 0 errors, 0 pending
       [jtestr]

    BUILD SUCCESSFUL
    Total time: 7 seconds




Wednesday, November 16, 11
Ant-Rake
                             Integration

Wednesday, November 16, 11
Problem…
                                            NUL


                                           Windows




                                         dev.null


                             /dev/null                 dev_null


                               Un*x                  everything else




Wednesday, November 16, 11
Ant…
     <condition property="dev.null" value="/dev/null">
       <os family="unix"/>
     </condition>
     <condition property="dev.null" value="NUL">
       <os family="windows"/>
     </condition>
     <condition property="dev.null" value="dev_null">
       <not>
         <or>
           <os family="unix"/>
           <os family="windows"/>
         </or>
       </not>
     </condition>




Wednesday, November 16, 11
Ruby
     if os.family == 'unix'
       :dev_null = '/dev/null'
     elsif os.family == 'windows'
       :dev_null = 'NUL'
     else
       :dev_null = 'dev_null'
     end




Wednesday, November 16, 11
Ant…
     <macrodef name="run-junit-1.8-short">
       <attribute name="compile.mode" default="OFF"/>
       <attribute name="jit.threshold" default="20"/>
       <attribute name="jit.maxsize" default="1000000000"/>
       <attribute name="reflection" default="false"/>
       <attribute name="thread.pooling" default="false"/>
       <attribute name="jvm.flags" default=""/>
     ⋮
     </macrodef>
     ⋮
     <target name="run-junit-compiled-short">
       <run-junit-1.8-short compile.mode="JIT" jit.threshold="0"/>
     </target>




Wednesday, November 16, 11
Ruby
     def run_junit_18_short(opts={})
       compile_mode   = opts[:compile_mode]     ||   'OFF'
       jit_threshold = opts[:jit_threshold]     ||   20
       jit_maxsize    = opts[:jit_maxsize]      ||   1000000000
       reflection     = opts[:reflection]       ||   false
       thread_pooling = opts[:thread_pooling]   ||   false
       jvm_flags      = opts[:jvm_flags]        ||   ""
       ⋮
     end

     def run_junit_compiled_short
       run_junit_18_short :compile_mode => 'JIT', :jit_threshold => 0
     end




Wednesday, November 16, 11
Ant tasks from Rake
     <path id="build.classpath">
       <fileset dir="${build.lib.dir}" includes="*.jar"/>
     </path>

     <path id="jruby.execute.classpath">
       <path refid="build.classpath"/>
       <pathelement path="${jruby.classes.dir}"/>
     </path>


     task :initialize_paths do
       ant.path(:id => "build.classpath") do
         fileset :dir => BUILD_LIB_DIR, :includes => "*.jar"
       end

       ant.path(:id => "jruby.execute.classpath") do
         path :refid => "build.classpath"
         pathelement :path => JRUBY_CLASSES_DIR
       end
     end



Wednesday, November 16, 11
Rake tasks as Ant targets
     <project name="foobar" default="top-level" basedir=".">
       <description>Builds, tests, and runs foobar.</description>

       <taskdef name="rakeimport"
     classname="org.jruby.ant.RakeImport"/>
       <rakeimport/>

         <target name="top-level" depends="its_in_rake" />

       <target name="its_in_ant">
         <echo message="ant: its_in_ant"/>

                                                   build.xml
       </target>
     </project>

    task :its_in_rake => [:setup, :its_in_ant]    do
      puts "it's in Rake"
    end

    task :setup do
      puts "setup in Rake"
    end                                                Rakefile
Wednesday, November 16, 11
Rake tasks as Ant targets
     <project name="foobar" default="top-level" basedir=".">
       <description>Builds, tests, and runs foobar.</description>

       <taskdef name="rakeimport"
     classname="org.jruby.ant.RakeImport"/>
       <rakeimport/>

         <target name="top-level" depends="its_in_rake" />

       <target name="its_in_ant">
         <echo message="ant: its_in_ant"/>

                                                   build.xml
       </target>
     </project>

    task :its_in_rake => [:setup, :its_in_ant]    do
      puts "it's in Rake"
    end

    task :setup do
      puts "setup in Rake"
    end

Wednesday, November 16, 11
Rake tasks as Ant targets
     <project name="foobar" default="top-level" basedir=".">
       <description>Builds, tests, and runs foobar.</description>

       <taskdef name="rakeimport"
     classname="org.jruby.ant.RakeImport"/>
       <rakeimport/>

         <target name="top-level" depends="its_in_rake" />

       <target name="its_in_ant">
         <echo message="ant: its_in_ant"/>
       </target>
     </project>

    task :its_in_rake => [:setup, :its_in_ant]    do
      puts "it's in Rake"
    end

    task :setup do
      puts "setup in Rake"
    end                                                Rakefile
Wednesday, November 16, 11
Rake tasks as Ant targets
     <project name="foobar" default="top-level" basedir=".">
       <description>Builds, tests, and runs foobar.</description>

       <taskdef name="rakeimport"
     classname="org.jruby.ant.RakeImport"/>
       <rakeimport/>

         <target name="top-level" depends="its_in_rake" />

       <target name="its_in_ant">
         <echo message="ant: its_in_ant"/>
       </target>
     </project>

    task :its_in_rake => [:setup, :its_in_ant]    do
      puts "it's in Rake"
    end

    task :setup do
      puts "setup in Rake"
    end

Wednesday, November 16, 11
Rake tasks as Ant targets
     <project name="foobar" default="top-level" basedir=".">
       <description>Builds, tests, and runs foobar.</description>

       <taskdef name="rakeimport"
     classname="org.jruby.ant.RakeImport"/>
       <rakeimport/>

         <target name="top-level" depends="its_in_rake" />

       <target name="its_in_ant">
         <echo message="ant: its_in_ant"/>
       </target>
     </project>

    task :its_in_rake => [:setup, :its_in_ant]    do
      puts "it's in Rake"
    end

    task :setup do
      puts "setup in Rake"
    end

Wednesday, November 16, 11
Rake tasks as Ant targets
     <project name="foobar" default="top-level" basedir=".">
       <description>Builds, tests, and runs foobar.</description>

       <taskdef name="rakeimport"
     classname="org.jruby.ant.RakeImport"/>
       <rakeimport/>

         <target name="top-level" depends="its_in_rake" />

       <target name="its_in_ant">
         <echo message="ant: its_in_ant"/>
       </target>
     </project>

    task :its_in_rake => [:setup, :its_in_ant]    do
      puts "it's in Rake"
    end

    task :setup do
      puts "setup in Rake"
    end

Wednesday, November 16, 11
Rake tasks as Ant targets
     <project name="foobar" default="top-level" basedir=".">
       <description>Builds, tests, and runs foobar.</description>

       <taskdef name="rakeimport"
     classname="org.jruby.ant.RakeImport"/>
       <rakeimport/>

         <target name="top-level" depends="its_in_rake" />

       <target name="its_in_ant">
         <echo message="ant: its_in_ant"/>
       </target>
     </project>

    task :its_in_rake => [:setup, :its_in_ant]    do
      puts "it's in Rake"
    end

    task :setup do
      puts "setup in Rake"
    end

Wednesday, November 16, 11
Rake tasks as Ant targets
                                         Buildfile: build.xml
     <project name="foobar" default="top-level" basedir=".">
                                         [rakeimport] (in /tmp/example2)
       <description>Builds, tests, and runs foobar.</description>

       <taskdef name="rakeimport"        setup:
     classname="org.jruby.ant.RakeImport"/>
       <rakeimport/>

         <target name="top-level" depends="its_in_rake" />

       <target name="its_in_ant">
         <echo message="ant: its_in_ant"/>
       </target>
     </project>

    task :its_in_rake => [:setup, :its_in_ant]    do
      puts "it's in Rake"
    end

    task :setup do
      puts "setup in Rake"
    end

Wednesday, November 16, 11
Rake tasks as Ant targets
                                         Buildfile: build.xml
     <project name="foobar" default="top-level" basedir=".">
                                         [rakeimport] (in /tmp/example2)
       <description>Builds, tests, and runs foobar.</description>

       <taskdef name="rakeimport"        setup:
                                         setup in Rake
     classname="org.jruby.ant.RakeImport"/>
       <rakeimport/>

         <target name="top-level" depends="its_in_rake" />

       <target name="its_in_ant">
         <echo message="ant: its_in_ant"/>
       </target>
     </project>

    task :its_in_rake => [:setup, :its_in_ant]    do
      puts "it's in Rake"
    end

    task :setup do
      puts "setup in Rake"
    end

Wednesday, November 16, 11
Rake tasks as Ant targets
                                         Buildfile: build.xml
     <project name="foobar" default="top-level" basedir=".">
                                         [rakeimport] (in /tmp/example2)
       <description>Builds, tests, and runs foobar.</description>

       <taskdef name="rakeimport"        setup:
                                         setup in Rake
     classname="org.jruby.ant.RakeImport"/>
       <rakeimport/>
                                         its_in_ant:
       <target name="top-level" depends="its_in_rake" />

       <target name="its_in_ant">
         <echo message="ant: its_in_ant"/>
       </target>
     </project>

    task :its_in_rake => [:setup, :its_in_ant]   do
      puts "it's in Rake"
    end

    task :setup do
      puts "setup in Rake"
    end

Wednesday, November 16, 11
Rake tasks as Ant targets
                                         Buildfile: build.xml
     <project name="foobar" default="top-level" basedir=".">
                                         [rakeimport] (in /tmp/example2)
       <description>Builds, tests, and runs foobar.</description>

       <taskdef name="rakeimport"        setup:
                                         setup in Rake
     classname="org.jruby.ant.RakeImport"/>
       <rakeimport/>
                                         its_in_ant:
       <target name="top-level" depends="its_in_rake" ant: its_in_ant
                                              [echo] />

       <target name="its_in_ant">
         <echo message="ant: its_in_ant"/>
       </target>
     </project>

    task :its_in_rake => [:setup, :its_in_ant]   do
      puts "it's in Rake"
    end

    task :setup do
      puts "setup in Rake"
    end

Wednesday, November 16, 11
Rake tasks as Ant targets
                                         Buildfile: build.xml
     <project name="foobar" default="top-level" basedir=".">
                                         [rakeimport] (in /tmp/example2)
       <description>Builds, tests, and runs foobar.</description>

       <taskdef name="rakeimport"        setup:
                                         setup in Rake
     classname="org.jruby.ant.RakeImport"/>
       <rakeimport/>
                                         its_in_ant:
       <target name="top-level" depends="its_in_rake" ant: its_in_ant
                                              [echo] />

       <target name="its_in_ant">        its_in_rake:
         <echo message="ant: its_in_ant"/>
       </target>
     </project>

    task :its_in_rake => [:setup, :its_in_ant]   do
      puts "it's in Rake"
    end

    task :setup do
      puts "setup in Rake"
    end

Wednesday, November 16, 11
Rake tasks as Ant targets
                                         Buildfile: build.xml
     <project name="foobar" default="top-level" basedir=".">
                                         [rakeimport] (in /tmp/example2)
       <description>Builds, tests, and runs foobar.</description>

       <taskdef name="rakeimport"        setup:
                                         setup in Rake
     classname="org.jruby.ant.RakeImport"/>
       <rakeimport/>
                                         its_in_ant:
       <target name="top-level" depends="its_in_rake" ant: its_in_ant
                                              [echo] />

       <target name="its_in_ant">        its_in_rake:
                                         it's in Rake
         <echo message="ant: its_in_ant"/>
       </target>
     </project>

    task :its_in_rake => [:setup, :its_in_ant]   do
      puts "it's in Rake"
    end

    task :setup do
      puts "setup in Rake"
    end

Wednesday, November 16, 11
Rake tasks as Ant targets
                                         Buildfile: build.xml
     <project name="foobar" default="top-level" basedir=".">
                                         [rakeimport] (in /tmp/example2)
       <description>Builds, tests, and runs foobar.</description>

       <taskdef name="rakeimport"        setup:
                                         setup in Rake
     classname="org.jruby.ant.RakeImport"/>
       <rakeimport/>
                                         its_in_ant:
       <target name="top-level" depends="its_in_rake" ant: its_in_ant
                                              [echo] />

       <target name="its_in_ant">        its_in_rake:
                                         it's in Rake
         <echo message="ant: its_in_ant"/>
       </target>
     </project>                          top-level:

                                        BUILD SUCCESSFUL
    task :its_in_rake => [:setup, :its_in_ant] time: 7 seconds
                                        Total    do
      puts "it's in Rake"
    end

    task :setup do
      puts "setup in Rake"
    end

Wednesday, November 16, 11
More…



                             http://bit.ly/rake_ant




Wednesday, November 16, 11
Maven and
                             RubyGems

Wednesday, November 16, 11
JRuby via Maven
   • Group ID: org.jruby
   • Artifact IDs: jruby, jruby-complete
     <dependencies>
       <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
         <scope>test</scope>
       </dependency>
       <dependency>
         <groupId>org.jruby</groupId>
         <artifactId>jruby</artifactId>
         <version>1.6.5</version>
       </dependency>
     </dependencies>




Wednesday, November 16, 11
Maven artifacts as gems
     jruby -S gem install mvn:org.clojure:clojure


                             maven




Wednesday, November 16, 11
Maven artifacts as gems
     jruby -S gem install mvn:org.clojure:clojure


                             group ID




Wednesday, November 16, 11
Maven artifacts as gems
     jruby -S gem install mvn:org.clojure:clojure


                                     artifact ID




Wednesday, November 16, 11
Maven artifacts as gems
     jruby -S gem install mvn:org.clojure:clojure




         Successfully installed mvn:org.clojure:clojure-1.4.0.a.2-java
         1 gem installed




                                   Some restrictions apply


Wednesday, November 16, 11
Maven artifacts as gems
   $ jruby -S irb
   irb(main):001:0> require 'mvn:org.clojure:clojure'
   => true
   irb(main):002:0> java_import Java::clojure.lang.PersistentHashMap
   => Java::ClojureLang::PersistentHashMap
   irb(main):003:0> phm = PersistentHashMap.create({:a => 100, :b =>
   200, :c => 300})
   => {:c=>300, :a=>100, :b=>200}
   irb(main):004:0> phm.delete_if {|k,v| k == :b}
   Java::JavaLang::UnsupportedOperationException:
     from clojure.lang.APersistentMap.remove(APersistentMap.java:273)
     from org.jruby.java.proxies.MapJavaProxy
   $RubyHashMap.internalDelete(MapJavaProxy.java:154)
     from org.jruby.RubyHash.delete(RubyHash.java:1407)
     from org.jruby.RubyHash$22.visit(RubyHash.java:1464)
     from org.jruby.java.proxies.MapJavaProxy
   $RubyHashMap.visitAll(MapJavaProxy.java:182)
   ⋮




Wednesday, November 16, 11
Foreign Function
                                     Interface
                                    Calling native functions




Wednesday, November 16, 11
Gamma function


                                 ∞
           Γ(z) =            ∫   t
                                 0
                                  z-1e-1   dt

Wednesday, November 16, 11
Apache Commons?
    org.apache.commons.math.special
    Class Gamma
    java.lang.Object
      org.apache.commons.math.special.Gamma

    public class Gamma
    extends java.lang.Object
    This is a utility class that provides computation methods related
    to the Gamma family of functions.



    Version:
    $Id: Gamma.java 1131229 2011-06-03 20:49:25Z luc $

Wednesday, November 16, 11
Apache Commons?
    org.apache.commons.math.special
    Class Gamma




                                               ize
                                    ?
    java.lang.Object

                                   e
      org.apache.commons.math.special.Gamma

                                  s

                                           Rs
    public class Gamma
                                en
    extends java.lang.Object
                             Lic
    This is a utility class that provides computation methods related



                                       JA
    to the Gamma family of functions.



    Version:
    $Id: Gamma.java 1131229 2011-06-03 20:49:25Z luc $

Wednesday, November 16, 11
for the coe cients in the series and estimate the error. After the
   Read academic paper
                     our new formula with some classical results. The numerical comp
                     equal number of ’correction’ terms the new formula is the most acc
                     recommended for computing the Gamma function for large real arg

                     Theorem 1. Let x                                 1, unction every n
                                                                         then for                            1, the following express
                                                                   ( x) f
                                              or the                                                                    !!x r
                                        sion f                                                        n 1
                                                                                                      X Gk                     2⇡
                                  expan                                                       x
                    ptotic                                          (x)             =                         + Rn (x)
                                               1
                                           Neme
                                                 s                                                                                ,
  New asym                          G    ˝
                                      ergo                                                    e           x2k                   x
                                                    8
                                           er 7, 200               05
                                                                                                       k=0
                                     ecemb                 t h08.0
                                    D                sl2ma
                                                     7/
                                                0.324
                     wherex.don.o = O
                         d
                           R i (x)         rg/1                 1
                                                               x2n
                                                                          and the Gk coe cients are given by
                                                                                   -
                             //                                                                      ap
                     http:                                                              otic series ter
                                                           ract
                                                                           re as ympt with bet -
                                                     Abst
                                                      , St
                                                                -De  Moiv a new one se of Stir
                                                          irling erted into      X wit h tho nd turns      Y 1 ✓
                                                                                                               k
                                                                                                                    B2r
                                                                                                                          ◆mr
                                                 ation n is conv           pared than 0.5 a rior to
                                          sform  G =   io k           com
                                   s tran ma funct formula is ts greater ically sup ed up
                                                                                                   e                          ,
                 U
                             serie         m                          n
                   sing a to the Ga The new al argume rms, num on has tu maxi-
                                                                                    er             rn       m ! 2r (2r 1)r
                       atio  n        ertie s.       for re        n’ te     m1 ,m2 ,...,msk( 0 al
                                                                                 ima ti       ing’
                                                                                                             r=1
             p roxim nce prop amanujan ’correctio 2m p+4mer+...+2kmu =2k  p rox rd Stirl r or eq
                         e                            f             rm a 1                       e
              co nverg lace and R number o closed-fo d as 3rd o nts great to which   2                  k
                     Lap               ual           t, a         goo           ume            e [7]
               ling, be, for eq side benefi about as                       al arg n older on
                                                                    or re
                o ut to em. As a                ich is an 1e-10 f ersion th   of a
                     where B denotes the r
                         th             si
                 all of the analy r rmall
                         g               o
                                           s wh er th
                                              s         ne xtend
                                                                 ed v  Bernoulli number [4]. Moreover, if x n
                  durin elative err article is a mainder.
                           r              s             e
                   mum Note: thi te of the r                                                                             !
                           ).               a
                   to 10 the estim
                                                                                                             8e1/5   the   ⇣ n ⌘2
                        adds                                                                                    n for a
                    it
                                                              |Rn (x)|  mptot+expxpeci+ormu ed
                                                                                    (n ic 1) li t f       ansio        l
                                                                                                                      2n
                          n                                                  w as y       an e       mnr(2n
                                                                                                      pa       1) (2⇡)       x
                     uctio                                           nt a n
                                                                           e        e give of, we co     for
              Introd                                              se
                                                                 pre
                                                           ct, we ual than
                                                                            one.
                                                                                  W      ro
                                                                                    the p n shows
                                                                                                   tha t
                                                                                                         hly
        1                 esult
                              nr                         a
                                                    abstr r or eq          .  After pariso         is hig
Wednesday, November 16, 11 1 i
                     e ma                    in the      ate          error       com       and i
                                                                                                 t
…and implement
if (Double.isNaN(x)) {
    value = Double.NaN;
    return;
}

double int_part = (int) x;
sign = (int_part % 2 == 0 && (x - int_part) != 0.0 && (x < 0)) ? -1 : 1




                                           !
if ((x - int_part) == 0.0 && 0 < int_part && int_part <= FACTORIAL.leng
    value = Math.log(FACTORIAL[(int) int_part - 1]);




                                         d
}




                                   r
else if (x < 10) {
    double rising_factorial = 1;



                                 a
    for (int i = 0; i < (int) Math.abs(x) - int_part + 10; i++) {
         rising_factorial *= (x + i);




                             H
    }
    NemesLogGamma l = new NemesLogGamma(x + (int) Math.abs(x) - int_par
    value = l.value - Math.log(Math.abs(rising_factorial));
} else {
    double temp = 0.0;
    for (int i = 0; i < NEMES_GAMMA_COEFF.length; i++) {
         temp += NEMES_GAMMA_COEFF[i] * 1.0 / Math.pow(x, i);
    }

        value = x * (Math.log(x) - 1 + Math.log(temp)) +
                (Math.log(2) + Math.log(Math.PI) - Math.log(x)) / 2.0;
}

Wednesday, November 16, 11
man…
     man gamma




Wednesday, November 16, 11
Not reinventing the wheel
     TGAMMA(3)                BSD Library Functions Manual        TGAMMA(3)

     NAME
                tgamma, lgamma, gamma -- gamma and log of gamma

     SYNOPSIS
          #include <math.h>

                double
                tgamma(double x);
     ⋮

     DESCRIPTION
          tgamma() calculates the gamma function of x. lgamma()
     calculates the natural logorithm of the absolute value of the
     gamma function of x. gamma() is the same function as tgamma.
     Its use is deprecated.

     ⋮



Wednesday, November 16, 11
JNI Workflow
                                      javah
                       Example.java             Example.h




                                                               cc
                                                 gamma.c            libgamma.dylib
                              javac




                                               Example.class




                                              $ java Example


Wednesday, November 16, 11
Example.java
     import java.util.*;

     class Example {
       native static double gamma(double x);

         static {
           System.loadLibrary("gamma");
         }

         public static void main(String args[]) {
           System.out.println(gamma(0.5));
         }
     }




Wednesday, November 16, 11
Example.h
     /* DO NOT EDIT THIS FILE - it is machine generated */
     #include <jni.h>
     /* Header for class Example */

     #ifndef _Included_Example
     #define _Included_Example
     #ifdef __cplusplus
     extern "C" {
     #endif
     /*
      * Class:      Example
      * Method:     gamma
      * Signature: (D)D
      */
     JNIEXPORT jdouble JNICALL Java_Example_gamma
        (JNIEnv *, jclass, jdouble);

     #ifdef __cplusplus
     }
     #endif
     #endif


Wednesday, November 16, 11
gamma.c
     #include "Example.h"
     #include <math.h>

     JNIEXPORT jdouble JNICALL Java_Example_gamma(JNIEnv* env,
     jclass jclass, jdouble jdbl) {
       return tgamma(jdbl);
     }




Wednesday, November 16, 11
Voilà!
     $ javah Example.java
     $ javac Example.java
     $ gcc -shared gamma.c -o libgamma.dylib 
       -I /Library/Java/JavaVirtualMachines/1.6.0_29-b11-397.jdk/
     Contents/Headers/

     $ java Example
     1.772453850905516




Wednesday, November 16, 11
gamma.rb
     require 'ffi'

     module Gamma
       extend FFI::Library
       ffi_lib FFI::Library::LIBC
       attach_function :tgamma, [:double], :double
     end

     puts Gamma::tgamma(0.5)




Wednesday, November 16, 11
Same result*!
     $ jruby gamma.rb
     1.77245385090552

     $ jruby --1.9 -e 'p Math::gamma(0.5)'
     1.77245385090552




Wednesday, November 16, 11
Benchmark
    $ jruby --1.9 bench_gamma.rb
    Rehearsal
    ----------------------------------------------------------------
    pure_java                       3.432000   0.000000   3.432000
    ( 3.432000)
    JNI                             0.409000   0.000000   0.409000
    ( 0.409000)
    FFI                             0.281000   0.000000   0.281000
    ( 0.281000)
    -------------------------------------------------------- total:
    4.122000sec

                                        user     system      total
    real
    pure_java                       2.849000   0.000000   2.849000
    ( 2.849000)
    JNI                             0.288000   0.000000   0.288000
    ( 0.289000)
    FFI                             0.219000   0.000000   0.219000
    ( 0.219000)



Wednesday, November 16, 11
But…


                                                                              d y?
                                                                       I n
                                                ut
                                           a b o
                         ha t
           W
                             h0p://www.flickr.com/photos/evablue/5665409533/

Wednesday, November 16, 11
Invokedynamic!
   • Only mainstream
     alternative JVM language
   • Worked closely with
     Hotspot team
   • JRuby master/1.7
   • Waiting for Java 1.7.0u2
     release
   • What does it mean for
     you?


Wednesday, November 16, 11
Benchmark
                                    Times faster than Ruby 1.9.3
              16
                                                                14.2x


              12

                 8                                                             7.4x

                                    5.5x
                                                         4.4x
                 4           2.7x
                                                  3.6x                  3.5x                 3.2x
                                           1.7x                                       1.8x          1.6x 1.9x


                 0
                               fib         +calls +consts +both richardsredblack
                                             JRuby on Java 6
                                             JRuby on invokedynamic
Wednesday, November 16, 11
Benchmark
                  0.300


                  0.225


                  0.150


                  0.075


                             0
                                 currentTimeMillis    Thread#name
                                    No indy          With indy
Wednesday, November 16, 11
Indy TODOs
   • Remaining invocation paths
         –varargs, super, all Java paths
   • Per-type specialization
         –Faster block-receiving calls
         –Faster module methods
   • More code in Ruby!




Wednesday, November 16, 11
Thank you!
   • Twitter: @hiro_asari
   • Github: BanzaiMan
         – Code examples:
              • jtestr-example
              • jni-gamma
              • test_example_deepthought
              • http://github.com/jruby/jruby




   http://www.engineyard.com/tryjruby
Wednesday, November 16, 11
References
   • http://ruby-lang.org
   • http://jruby.org
   • http://pragprog.com/book/jruby/using-jruby
   • http://rubyonrails.org
   • http://torquebox.org
   • http://tomcat.apache.org
   • http://jetty.codehause.org
   • http://glassfish.java.net
   • https://www.relishapp.com/rspec
   • http://cukes.info
Wednesday, November 16, 11
References
   • http://jtestr.codehaus.org/
   • http://www.ebyte.it/library/docs/math07/
     GammaApproximation.html
   • http://download.oracle.com/javase/6/docs/
     technotes/guides/jni/
   • http://jcp.org/en/jsr/detail?id=292




Wednesday, November 16, 11

Contenu connexe

En vedette

Spring into rails
Spring into railsSpring into rails
Spring into railsHiro Asari
 
Using Java from Ruby with JRuby IRB
Using Java from Ruby with JRuby IRBUsing Java from Ruby with JRuby IRB
Using Java from Ruby with JRuby IRBHiro Asari
 
Web Services
Web ServicesWeb Services
Web ServicesSHC
 
Wikipedia en Bibliotheken: een presentatie voor Mediacoaches
Wikipedia en Bibliotheken: een presentatie voor MediacoachesWikipedia en Bibliotheken: een presentatie voor Mediacoaches
Wikipedia en Bibliotheken: een presentatie voor MediacoachesEdwin Mijnsbergen
 
Afrikaans Right of REVOLUTION & Political CORRUPTION
Afrikaans   Right of REVOLUTION & Political CORRUPTIONAfrikaans   Right of REVOLUTION & Political CORRUPTION
Afrikaans Right of REVOLUTION & Political CORRUPTIONVogelDenise
 
Presentatie-handout van de lancering van het Handboek Content Strategie van d...
Presentatie-handout van de lancering van het Handboek Content Strategie van d...Presentatie-handout van de lancering van het Handboek Content Strategie van d...
Presentatie-handout van de lancering van het Handboek Content Strategie van d...AtMost and AtMostTV
 
Rubyを持て、世界に出よう
Rubyを持て、世界に出ようRubyを持て、世界に出よう
Rubyを持て、世界に出ようHiro Asari
 
Iadd2 0910 Q2 Information Architecture And Navigation
Iadd2 0910 Q2   Information Architecture And NavigationIadd2 0910 Q2   Information Architecture And Navigation
Iadd2 0910 Q2 Information Architecture And NavigationHans Kemp
 

En vedette (11)

Spring into rails
Spring into railsSpring into rails
Spring into rails
 
JRuby and You
JRuby and YouJRuby and You
JRuby and You
 
Using Java from Ruby with JRuby IRB
Using Java from Ruby with JRuby IRBUsing Java from Ruby with JRuby IRB
Using Java from Ruby with JRuby IRB
 
Web Services
Web ServicesWeb Services
Web Services
 
SAMBA4-BLANKONF2012
SAMBA4-BLANKONF2012SAMBA4-BLANKONF2012
SAMBA4-BLANKONF2012
 
Wikipedia en Bibliotheken: een presentatie voor Mediacoaches
Wikipedia en Bibliotheken: een presentatie voor MediacoachesWikipedia en Bibliotheken: een presentatie voor Mediacoaches
Wikipedia en Bibliotheken: een presentatie voor Mediacoaches
 
Afrikaans Right of REVOLUTION & Political CORRUPTION
Afrikaans   Right of REVOLUTION & Political CORRUPTIONAfrikaans   Right of REVOLUTION & Political CORRUPTION
Afrikaans Right of REVOLUTION & Political CORRUPTION
 
Presentatie-handout van de lancering van het Handboek Content Strategie van d...
Presentatie-handout van de lancering van het Handboek Content Strategie van d...Presentatie-handout van de lancering van het Handboek Content Strategie van d...
Presentatie-handout van de lancering van het Handboek Content Strategie van d...
 
Rubyを持て、世界に出よう
Rubyを持て、世界に出ようRubyを持て、世界に出よう
Rubyを持て、世界に出よう
 
Developing and Assessing Teacher Effectiveness
Developing and Assessing Teacher EffectivenessDeveloping and Assessing Teacher Effectiveness
Developing and Assessing Teacher Effectiveness
 
Iadd2 0910 Q2 Information Architecture And Navigation
Iadd2 0910 Q2   Information Architecture And NavigationIadd2 0910 Q2   Information Architecture And Navigation
Iadd2 0910 Q2 Information Architecture And Navigation
 

Similaire à JRuby: Enhancing Java Developers' Lives

GeometricObject.javapublic interface GeometricObject { Declari.pdf
GeometricObject.javapublic interface GeometricObject { Declari.pdfGeometricObject.javapublic interface GeometricObject { Declari.pdf
GeometricObject.javapublic interface GeometricObject { Declari.pdfanokhilalmobile
 
MultiSphere.java public class MultiSphere { public static vo.pdf
MultiSphere.java public class MultiSphere { public static vo.pdfMultiSphere.java public class MultiSphere { public static vo.pdf
MultiSphere.java public class MultiSphere { public static vo.pdfrakeshboobna354
 
C++ classes tutorials
C++ classes tutorialsC++ classes tutorials
C++ classes tutorialskailash454
 
C++ classes tutorials
C++ classes tutorialsC++ classes tutorials
C++ classes tutorialskksupaul
 
10_interfacesjavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.pdf
10_interfacesjavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.pdf10_interfacesjavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.pdf
10_interfacesjavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.pdfRihabBENLAMINE
 
How to use Map() Filter() and Reduce() functions in Python | Edureka
How to use Map() Filter() and Reduce() functions in Python | EdurekaHow to use Map() Filter() and Reduce() functions in Python | Edureka
How to use Map() Filter() and Reduce() functions in Python | EdurekaEdureka!
 
Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performanceintelliyole
 
C++ classes tutorials
C++ classes tutorialsC++ classes tutorials
C++ classes tutorialsFALLEE31188
 

Similaire à JRuby: Enhancing Java Developers' Lives (10)

GeometricObject.javapublic interface GeometricObject { Declari.pdf
GeometricObject.javapublic interface GeometricObject { Declari.pdfGeometricObject.javapublic interface GeometricObject { Declari.pdf
GeometricObject.javapublic interface GeometricObject { Declari.pdf
 
MultiSphere.java public class MultiSphere { public static vo.pdf
MultiSphere.java public class MultiSphere { public static vo.pdfMultiSphere.java public class MultiSphere { public static vo.pdf
MultiSphere.java public class MultiSphere { public static vo.pdf
 
C++ classes tutorials
C++ classes tutorialsC++ classes tutorials
C++ classes tutorials
 
C++ classes tutorials
C++ classes tutorialsC++ classes tutorials
C++ classes tutorials
 
Oo ps
Oo psOo ps
Oo ps
 
oop objects_classes
oop objects_classesoop objects_classes
oop objects_classes
 
10_interfacesjavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.pdf
10_interfacesjavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.pdf10_interfacesjavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.pdf
10_interfacesjavaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.pdf
 
How to use Map() Filter() and Reduce() functions in Python | Edureka
How to use Map() Filter() and Reduce() functions in Python | EdurekaHow to use Map() Filter() and Reduce() functions in Python | Edureka
How to use Map() Filter() and Reduce() functions in Python | Edureka
 
Kotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime PerformanceKotlin Bytecode Generation and Runtime Performance
Kotlin Bytecode Generation and Runtime Performance
 
C++ classes tutorials
C++ classes tutorialsC++ classes tutorials
C++ classes tutorials
 

Dernier

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 

Dernier (20)

A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 

JRuby: Enhancing Java Developers' Lives

  • 1. JRuby: Enhancing Java Developers' Lives Hiro Asari @hiro_asari JRuby Support Engineer Engine Yard @engineyard Wednesday, November 16, 11
  • 2. JRuby: a Brief History Where it came from, and where it is now Wednesday, November 16, 11
  • 3. History • September 10, 2001 Source:(Wikipedia Wednesday, November 16, 11
  • 5. History • 10+ years old • Led by Charles Nutter and Tom Enebo • 14.800+ commits Wednesday, November 16, 11
  • 6. Project Status • Current Stable Release: 1.6.5 • Compatible with Ruby 1.8.7 and 1.9.2 • Supports Rails 3.1 Wednesday, November 16, 11
  • 7. Getting JRuby h0p://jruby.org/download Wednesday, November 16, 11
  • 8. Trying JRuby h0p://jruby.org/tryjruby Wednesday, November 16, 11
  • 10. Quick Tour of Ruby A brief overview of the language Wednesday, November 16, 11
  • 11. Classes public class Circle extends Shape { class Circle < Shape private final int radius; def initialize(radius) @radius = radius public Circle(int radius) { end this.radius = radius; } attr_reader :radius public int getRadius() { return radius; def area } Math::PI*(@radius ** public double getArea() { 2) return Math.PI * Math.pow(radius,2); end } end public static void main(String[] a) { double area=new Circle(2).getArea(); puts Circle.new(2).area System.out.println(area); } } Wednesday, November 16, 11
  • 12. Single Inheritance Same Thing public class Circle extends Shape { class Circle < Shape private final int radius; def initialize(radius) @radius = radius public Circle(int radius) { end this.radius = radius; } attr_reader :radius public int getRadius() { return radius; def area } Math::PI*(@radius ** public double getArea() { 2) return Math.PI * Math.pow(radius,2); end } end public static void main(String[] a) { double area=new Circle(2).getArea(); puts Circle.new(2).area System.out.println(area); } } Wednesday, November 16, 11
  • 13. Constructor public class Circle extends Shape { class Circle < Shape private final int radius; def initialize(radius) @radius = radius public Circle(int radius) { end this.radius = radius; } attr_reader :radius public int getRadius() { return radius; def area } Math::PI*(@radius ** public double getArea() { 2) return Math.PI * Math.pow(radius,2); end } end public static void main(String[] a) { double area=new Circle(2).getArea(); puts Circle.new(2).area System.out.println(area); } } Wednesday, November 16, 11
  • 14. No Type Declarations public class Circle extends Shape { class Circle < Shape private final int radius; def initialize(radius) @radius = radius public Circle(int radius) { end this.radius = radius; } attr_reader :radius public int getRadius() { return radius; def area } Math::PI*(@radius ** public double getArea() { 2) return Math.PI * Math.pow(radius,2); end } end public static void main(String[] a) { double area=new Circle(2).getArea(); puts Circle.new(2).area System.out.println(area); } } Wednesday, November 16, 11
  • 15. Instance Variables ‘@’ == ‘this.’ and is mandatory public class Circle extends Shape { class Circle < Shape private final int radius; def initialize(radius) @radius = radius public Circle(int radius) { end this.radius = radius; } attr_reader :radius public int getRadius() { return radius; def area } Math::PI*(@radius ** public double getArea() { 2) return Math.PI * Math.pow(radius,2); end } end public static void main(String[] a) { double area=new Circle(2).getArea(); puts Circle.new(2).area System.out.println(area); } } Wednesday, November 16, 11
  • 16. Working with Instance Variables Common tasks are easy public class Circle extends Shape { class Circle < Shape private final int radius; def initialize(radius) @radius = radius public Circle(int radius) { end this.radius = radius; } attr_reader :radius public int getRadius() { return radius; def area } Math::PI*(@radius ** public double getArea() { 2) return Math.PI * Math.pow(radius,2); end } end public static void main(String[] a) { double area=new Circle(2).getArea(); puts Circle.new(2).area System.out.println(area); } } Wednesday, November 16, 11
  • 17. Symbols :identifier • Prefixed with a colon • Uniquely defined in a runtime Wednesday, November 16, 11
  • 18. Point of No Return Last Expression is always return value public class Circle extends Shape { class Circle < Shape private final int radius; def initialize(radius) @radius = radius public Circle(int radius) { end this.radius = radius; } attr_reader :radius public int getRadius() { return radius; def area } Math::PI*(@radius ** public double getArea() { 2) return Math.PI * Math.pow(radius,2); end } end public static void main(String[] a) { double area=new Circle(2).getArea(); puts Circle.new(2).area System.out.println(area); } } Wednesday, November 16, 11
  • 19. .new is just a class method public class Circle extends Shape { class Circle < Shape private final int radius; def initialize(radius) @radius = radius public Circle(int radius) { end this.radius = radius; } attr_reader :radius public int getRadius() { return radius; def area } Math::PI*(@radius ** public double getArea() { 2) return Math.PI * Math.pow(radius,2); end } end public static void main(String[] a) { double area=new Circle(2).getArea(); puts Circle.new(2).area System.out.println(area); } } Wednesday, November 16, 11
  • 20. Blocks/Closures • Pass an anonymous function to a method call # Look mom...no boilerplate! my_open(file) do |io| letters.group_by {|b| b.zip_code } first_line = io.gets # ... end def my_open(file, mode='r') io = File.open(file) yield io button.action_performed do ensure exit io.close end end Wednesday, November 16, 11
  • 21. Modules module Enumerable class MyTree def find(if_none = nil) include Enumerable each { |o| return o if yield(o) } if_none # tree impl not shown :) end def each # Many other methods not shown # yield each element # in tree def collect end ary = [] end each { |o| ary << yield(o) } ary end end dude = people.find { |person| person.id == 123 } floats = [1,2].collect { |int| int.to_f } # => [1.0, 2.0] Wednesday, November 16, 11
  • 22. Everything is an Expression class Color COLORS = {:red => 0xff0000, :green => 0x00ff00, :blue => 0x0000ff} COLORS.each do |name, value| define_method(name) do value end end end Wednesday, November 16, 11
  • 23. Classes/Modules are open class MyTree def each #... end end #... later in source #... maybe even different file class MyTree def debug #... end end Wednesday, November 16, 11
  • 24. Pure OO Language • Everything is an object MyTree.foo #=> method call 12 + 8 #=> here, '+' is a method on Fixnum, 12. 12.to_s(8) #=> "14" puts 11.odd? #=> true Wednesday, November 16, 11
  • 25. JRuby on Rails Ruby's Killer app Wednesday, November 16, 11
  • 26. Java Web Frameworks Devoxx 2010 Wednesday, November 16, 11
  • 27. Java Web Frameworks h0p://j.mp/raible<jvm<frameworks COMPARING JVM WEB FRAMEWORKS Matt Raible http://raibledesigns.com Images by Stuck in Customs - http://www.flickr.com/photos/stuckincustoms © 2010, Raible Designs © 2010 Raible Designs Wednesday, November 16, 11
  • 28. Install Rails $ jruby -S gem install rails Fetching: multi_json-1.0.3.gem (100%) ⋮ Fetching: bundler-1.0.21.gem (100%) Fetching: rails-3.1.1.gem (100%) Successfully installed multi_json-1.0.3 Successfully installed activesupport-3.1.1 ⋮ Successfully installed thor-0.14.6 Successfully installed rack-ssl-1.3.2 Successfully installed json-1.6.1-java Successfully installed rdoc-3.11 Successfully installed railties-3.1.1 Successfully installed bundler-1.0.21 Successfully installed rails-3.1.1 31 gems installed Wednesday, November 16, 11
  • 29. Generate Rails app $ jruby -S rails new awesomeapp create ⋮ create vendor/plugins create vendor/plugins/.gitkeep run bundle install Fetching source index for http://rubygems.org/ Using rake (0.9.2.2) ⋮ Using json (1.6.1) Using rdoc (3.11) Using thor (0.14.6) Using railties (3.1.1) Installing coffee-rails (3.1.1) Installing jquery-rails (1.0.16) Installing jruby-openssl (0.7.4) Using rails (3.1.1) Installing sass (3.1.10) Installing sass-rails (3.1.4) Installing uglifier (1.0.4) Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed. Wednesday, November 16, 11
  • 30. Rails Scaffolding $ jruby -S rails generate scaffold person name:string email:string invoke active_record create db/migrate/20111107052142_create_people.rb create app/models/person.rb ⋮ create app/views/people/show.html.erb create app/views/people/new.html.erb create app/views/people/_form.html.erb invoke test_unit create test/functional/people_controller_test.rb invoke helper create app/helpers/people_helper.rb invoke test_unit create test/unit/helpers/people_helper_test.rb invoke assets invoke coffee create app/assets/javascripts/people.js.coffee invoke scss create app/assets/stylesheets/people.css.scss invoke scss create app/assets/stylesheets/scaffolds.css.scss Wednesday, November 16, 11
  • 31. Migrate Database $ jruby -S rake db:migrate == CreatePeople: migrating ==================================== -- create_table(:people) -> 0.0040s -> 0 rows == CreatePeople: migrated (0.0040s) =========================== Wednesday, November 16, 11
  • 32. Start Server $ jruby -S rails server => Booting WEBrick => Rails 3.1.1 application starting in development on http:// 0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server [2011-11-07 00:26:30] INFO WEBrick 1.3.1 [2011-11-07 00:26:30] INFO ruby 1.8.7 (2011-11-05) [java] [2011-11-07 00:26:30] INFO WEBrick::HTTPServer#start: pid=40454 port=3000 Wednesday, November 16, 11
  • 34. app/controllers/people_controller.rb class PeopleController < ApplicationController # GET /people # GET /people.json def index @people = Person.all respond_to do |format| format.html # index.html.erb format.json { render :json => @people } end end ⋮ end Wednesday, November 16, 11
  • 35. JSON out of the box Wednesday, November 16, 11
  • 36. app/models/person.rb class Person < ActiveRecord::Base end Wednesday, November 16, 11
  • 38. Rails IDE and text editors jetbrains.com/ruby/ redcareditor.com netbeans.org •emacs •vi(m) •TextMate Wednesday, November 16, 11
  • 39. JRuby in Java web app Requests JRuby / /vets /rack/ Java/ Spring App Wednesday, November 16, 11
  • 40. JRuby in Java web app diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 8d02684..60ed6cb 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -87,6 +87,21 @@ <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> + + <listener> + <listener-class>org.jruby.rack.RackServletContextListener</listener-class> + </listener> + + <servlet> + <servlet-name>rack</servlet-name> + <servlet-class>org.jruby.rack.RackServlet</servlet-class> + </servlet> + + <servlet-mapping> + <servlet-name>rack</servlet-name> + <url-pattern>/rack/*</url-pattern> + </servlet-mapping> + <!-- Defines the 'default' servlet (usually for service static resources). Wednesday, November 16, 11
  • 41. Rails in Java web app Requests / /vets JRuby /owners Java/ / /vets /owners /1/pets Spring App Wednesday, November 16, 11
  • 42. Rails in Java web app diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 60ed6cb..f64b34d 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -92,16 +92,6 @@ <listener-class>org.jruby.rack.RackServletContextListener</listener-class> </listener> - <servlet> - <servlet-name>rack</servlet-name> - <servlet-class>org.jruby.rack.RackServlet</servlet-class> - </servlet> - - <servlet-mapping> - <servlet-name>rack</servlet-name> - <url-pattern>/rack/*</url-pattern> - </servlet-mapping> - <!-- Defines the 'default' servlet (usually for service static resources). @@ -162,6 +152,16 @@ <url-pattern>/</url-pattern> </servlet-mapping> + <filter> + <filter-name>RackFilter</filter-name> + <filter-class>org.jruby.rack.RubyFirstRackFilter</filter-class> + </filter> + + <filter-mapping> + <filter-name>RackFilter</filter-name> + <url-pattern>/*</url-pattern> + </filter-mapping> + <filter> <filter-name>httpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> Wednesday, November 16, 11
  • 43. More… h0p://bit.ly/refactoring<to<rails h0p://vimeo.com/25410705 Wednesday, November 16, 11
  • 44. Testing Libraries Test-Driven Development Wednesday, November 16, 11
  • 45. Testing Number of Tests Written (1000's) 100 75 50 25 Easy Hard Ease of Writing Tests Wednesday, November 16, 11
  • 46. Test files $ jruby -S rails g scaffold person name:string email:string invoke active_record create db/migrate/20111107052142_create_people.rb create app/models/person.rb ⋮ create app/views/people/show.html.erb create app/views/people/new.html.erb create app/views/people/_form.html.erb invoke test_unit create test/functional/people_controller_test.rb invoke helper create app/helpers/people_helper.rb invoke test_unit create test/unit/helpers/people_helper_test.rb invoke assets invoke coffee create app/assets/javascripts/people.js.coffee invoke scss create app/assets/stylesheets/people.css.scss invoke scss create app/assets/stylesheets/scaffolds.css.scss Wednesday, November 16, 11
  • 47. DeepThought.java class DeepThought { public static int answerToEverything(Object obj) { return 42; } public static String getName() { return "DeepThought"; } } Wednesday, November 16, 11
  • 48. RSpec require 'rspec' require 'java' java_import 'DeepThought' describe 'DeepThought' do describe '.answerToEverything' do it "should return 42, given any input" do DeepThought.answerToEverything(nil).should == 42 DeepThought.answerToEverything(true).should == 42 end end describe '.getName' do it "should return 'DeepThought'" do DeepThought.name.should == "DeepThought" end end end Wednesday, November 16, 11
  • 49. RSpec $ javac DeepThrought.java $ jruby -rubygems deep_thought_spec.rb .. Finished in 0.013 seconds 2 examples, 0 failures Wednesday, November 16, 11
  • 50. Cucumber Feature: AnswerToEverything Ask DeepThought the answer to everything Scenario: Ask a question Given nil as input Then the result should be 42 Feature: getName Ask DeepThought what its name is Scenario: get name When asked the name Then it answers the name as "DeepThought" Wednesday, November 16, 11
  • 51. Cucumber $ jruby -S cucumber Feature: AnswerToEverything Ask DeepThought the answer to everything Scenario: Ask a question # features/answer.feature:4 Given nil as input # features/step_definitions… Then the result should be 42 # features/step_definitions… Feature: getName Ask DeepThought what its name is Scenario: get name # features/… When asked the name # features/… Then it answers the name as "DeepThought" # features/… 2 scenarios (2 passed) 4 steps (4 passed) 0m0.065s Wednesday, November 16, 11
  • 52. JTestr • Bridge for Java to make use of Ruby testing • Integrates with both Ant and Maven • Allows mocking of non-final Java class/method • Written by Ola Bini Wednesday, November 16, 11
  • 53. JTestr Example my_project/ build.xml! test/ test_hashmap.rb hashmap_spec.rb lib/ jtestr.jar src/ <your source ;) > Wednesday, November 16, 11
  • 54. JTestr in Ant <?xml version="1.0" encoding="UTF-8"?> <project basedir="." default="jar" name="JRuby"> <target name="test" description="Runs all tests"> <taskdef name="jtestr" classname="org.jtestr.ant.JtestRAntRunner" classpath="lib/jtestr.jar"/> <jtestr/> </target> </project> Wednesday, November 16, 11
  • 55. Ruby’s test/unit test/test_hashmap.rb class HashMapTests < Test::Unit::TestCase def setup @map = java.util.HashMap.new end def test_that_an_entry_can_be_added @map.put "foo", "bar" assert_equal "bar", @map.get("foo") end def test_empty_key_set_iterator_throws_exception assert_raises(java.util.NoSuchElementException) do @map.key_set.iterator.next end end end Wednesday, November 16, 11
  • 56. RSpec revisited test/hashmap_spec.rb require 'java' java_import java.util.HashMap describe "An empty", HashMap do before :each do @hash_map = java.util.HashMap.new end it "should be able to add an entry to it" do @hash_map.put "foo", "bar" @hash_map.get("foo").should == "bar" end it "should not be empty after an entry has been added to it" do @hash_map.put "foo", "bar" @hash_map.should_not be_empty end it "should be empty" do @hash_map.should be_empty end end Wednesday, November 16, 11
  • 57. Results $ ant test Buildfile: /Users/asari/Development/projects/jtestr-example/ build.xml test: [jtestr] Other TestUnit: 2 tests, 0 failures, 0 errors [jtestr] [jtestr] Other Spec: 3 examples, 0 failures, 0 errors [jtestr] [jtestr] Total: 5 tests, 0 failures, 0 errors, 0 pending [jtestr] BUILD SUCCESSFUL Total time: 7 seconds Wednesday, November 16, 11
  • 58. Ant-Rake Integration Wednesday, November 16, 11
  • 59. Problem… NUL Windows dev.null /dev/null dev_null Un*x everything else Wednesday, November 16, 11
  • 60. Ant… <condition property="dev.null" value="/dev/null"> <os family="unix"/> </condition> <condition property="dev.null" value="NUL"> <os family="windows"/> </condition> <condition property="dev.null" value="dev_null"> <not> <or> <os family="unix"/> <os family="windows"/> </or> </not> </condition> Wednesday, November 16, 11
  • 61. Ruby if os.family == 'unix' :dev_null = '/dev/null' elsif os.family == 'windows' :dev_null = 'NUL' else :dev_null = 'dev_null' end Wednesday, November 16, 11
  • 62. Ant… <macrodef name="run-junit-1.8-short"> <attribute name="compile.mode" default="OFF"/> <attribute name="jit.threshold" default="20"/> <attribute name="jit.maxsize" default="1000000000"/> <attribute name="reflection" default="false"/> <attribute name="thread.pooling" default="false"/> <attribute name="jvm.flags" default=""/> ⋮ </macrodef> ⋮ <target name="run-junit-compiled-short"> <run-junit-1.8-short compile.mode="JIT" jit.threshold="0"/> </target> Wednesday, November 16, 11
  • 63. Ruby def run_junit_18_short(opts={}) compile_mode = opts[:compile_mode] || 'OFF' jit_threshold = opts[:jit_threshold] || 20 jit_maxsize = opts[:jit_maxsize] || 1000000000 reflection = opts[:reflection] || false thread_pooling = opts[:thread_pooling] || false jvm_flags = opts[:jvm_flags] || "" ⋮ end def run_junit_compiled_short run_junit_18_short :compile_mode => 'JIT', :jit_threshold => 0 end Wednesday, November 16, 11
  • 64. Ant tasks from Rake <path id="build.classpath"> <fileset dir="${build.lib.dir}" includes="*.jar"/> </path> <path id="jruby.execute.classpath"> <path refid="build.classpath"/> <pathelement path="${jruby.classes.dir}"/> </path> task :initialize_paths do ant.path(:id => "build.classpath") do fileset :dir => BUILD_LIB_DIR, :includes => "*.jar" end ant.path(:id => "jruby.execute.classpath") do path :refid => "build.classpath" pathelement :path => JRUBY_CLASSES_DIR end end Wednesday, November 16, 11
  • 65. Rake tasks as Ant targets <project name="foobar" default="top-level" basedir="."> <description>Builds, tests, and runs foobar.</description> <taskdef name="rakeimport" classname="org.jruby.ant.RakeImport"/> <rakeimport/> <target name="top-level" depends="its_in_rake" /> <target name="its_in_ant"> <echo message="ant: its_in_ant"/> build.xml </target> </project> task :its_in_rake => [:setup, :its_in_ant] do puts "it's in Rake" end task :setup do puts "setup in Rake" end Rakefile Wednesday, November 16, 11
  • 66. Rake tasks as Ant targets <project name="foobar" default="top-level" basedir="."> <description>Builds, tests, and runs foobar.</description> <taskdef name="rakeimport" classname="org.jruby.ant.RakeImport"/> <rakeimport/> <target name="top-level" depends="its_in_rake" /> <target name="its_in_ant"> <echo message="ant: its_in_ant"/> build.xml </target> </project> task :its_in_rake => [:setup, :its_in_ant] do puts "it's in Rake" end task :setup do puts "setup in Rake" end Wednesday, November 16, 11
  • 67. Rake tasks as Ant targets <project name="foobar" default="top-level" basedir="."> <description>Builds, tests, and runs foobar.</description> <taskdef name="rakeimport" classname="org.jruby.ant.RakeImport"/> <rakeimport/> <target name="top-level" depends="its_in_rake" /> <target name="its_in_ant"> <echo message="ant: its_in_ant"/> </target> </project> task :its_in_rake => [:setup, :its_in_ant] do puts "it's in Rake" end task :setup do puts "setup in Rake" end Rakefile Wednesday, November 16, 11
  • 68. Rake tasks as Ant targets <project name="foobar" default="top-level" basedir="."> <description>Builds, tests, and runs foobar.</description> <taskdef name="rakeimport" classname="org.jruby.ant.RakeImport"/> <rakeimport/> <target name="top-level" depends="its_in_rake" /> <target name="its_in_ant"> <echo message="ant: its_in_ant"/> </target> </project> task :its_in_rake => [:setup, :its_in_ant] do puts "it's in Rake" end task :setup do puts "setup in Rake" end Wednesday, November 16, 11
  • 69. Rake tasks as Ant targets <project name="foobar" default="top-level" basedir="."> <description>Builds, tests, and runs foobar.</description> <taskdef name="rakeimport" classname="org.jruby.ant.RakeImport"/> <rakeimport/> <target name="top-level" depends="its_in_rake" /> <target name="its_in_ant"> <echo message="ant: its_in_ant"/> </target> </project> task :its_in_rake => [:setup, :its_in_ant] do puts "it's in Rake" end task :setup do puts "setup in Rake" end Wednesday, November 16, 11
  • 70. Rake tasks as Ant targets <project name="foobar" default="top-level" basedir="."> <description>Builds, tests, and runs foobar.</description> <taskdef name="rakeimport" classname="org.jruby.ant.RakeImport"/> <rakeimport/> <target name="top-level" depends="its_in_rake" /> <target name="its_in_ant"> <echo message="ant: its_in_ant"/> </target> </project> task :its_in_rake => [:setup, :its_in_ant] do puts "it's in Rake" end task :setup do puts "setup in Rake" end Wednesday, November 16, 11
  • 71. Rake tasks as Ant targets <project name="foobar" default="top-level" basedir="."> <description>Builds, tests, and runs foobar.</description> <taskdef name="rakeimport" classname="org.jruby.ant.RakeImport"/> <rakeimport/> <target name="top-level" depends="its_in_rake" /> <target name="its_in_ant"> <echo message="ant: its_in_ant"/> </target> </project> task :its_in_rake => [:setup, :its_in_ant] do puts "it's in Rake" end task :setup do puts "setup in Rake" end Wednesday, November 16, 11
  • 72. Rake tasks as Ant targets Buildfile: build.xml <project name="foobar" default="top-level" basedir="."> [rakeimport] (in /tmp/example2) <description>Builds, tests, and runs foobar.</description> <taskdef name="rakeimport" setup: classname="org.jruby.ant.RakeImport"/> <rakeimport/> <target name="top-level" depends="its_in_rake" /> <target name="its_in_ant"> <echo message="ant: its_in_ant"/> </target> </project> task :its_in_rake => [:setup, :its_in_ant] do puts "it's in Rake" end task :setup do puts "setup in Rake" end Wednesday, November 16, 11
  • 73. Rake tasks as Ant targets Buildfile: build.xml <project name="foobar" default="top-level" basedir="."> [rakeimport] (in /tmp/example2) <description>Builds, tests, and runs foobar.</description> <taskdef name="rakeimport" setup: setup in Rake classname="org.jruby.ant.RakeImport"/> <rakeimport/> <target name="top-level" depends="its_in_rake" /> <target name="its_in_ant"> <echo message="ant: its_in_ant"/> </target> </project> task :its_in_rake => [:setup, :its_in_ant] do puts "it's in Rake" end task :setup do puts "setup in Rake" end Wednesday, November 16, 11
  • 74. Rake tasks as Ant targets Buildfile: build.xml <project name="foobar" default="top-level" basedir="."> [rakeimport] (in /tmp/example2) <description>Builds, tests, and runs foobar.</description> <taskdef name="rakeimport" setup: setup in Rake classname="org.jruby.ant.RakeImport"/> <rakeimport/> its_in_ant: <target name="top-level" depends="its_in_rake" /> <target name="its_in_ant"> <echo message="ant: its_in_ant"/> </target> </project> task :its_in_rake => [:setup, :its_in_ant] do puts "it's in Rake" end task :setup do puts "setup in Rake" end Wednesday, November 16, 11
  • 75. Rake tasks as Ant targets Buildfile: build.xml <project name="foobar" default="top-level" basedir="."> [rakeimport] (in /tmp/example2) <description>Builds, tests, and runs foobar.</description> <taskdef name="rakeimport" setup: setup in Rake classname="org.jruby.ant.RakeImport"/> <rakeimport/> its_in_ant: <target name="top-level" depends="its_in_rake" ant: its_in_ant [echo] /> <target name="its_in_ant"> <echo message="ant: its_in_ant"/> </target> </project> task :its_in_rake => [:setup, :its_in_ant] do puts "it's in Rake" end task :setup do puts "setup in Rake" end Wednesday, November 16, 11
  • 76. Rake tasks as Ant targets Buildfile: build.xml <project name="foobar" default="top-level" basedir="."> [rakeimport] (in /tmp/example2) <description>Builds, tests, and runs foobar.</description> <taskdef name="rakeimport" setup: setup in Rake classname="org.jruby.ant.RakeImport"/> <rakeimport/> its_in_ant: <target name="top-level" depends="its_in_rake" ant: its_in_ant [echo] /> <target name="its_in_ant"> its_in_rake: <echo message="ant: its_in_ant"/> </target> </project> task :its_in_rake => [:setup, :its_in_ant] do puts "it's in Rake" end task :setup do puts "setup in Rake" end Wednesday, November 16, 11
  • 77. Rake tasks as Ant targets Buildfile: build.xml <project name="foobar" default="top-level" basedir="."> [rakeimport] (in /tmp/example2) <description>Builds, tests, and runs foobar.</description> <taskdef name="rakeimport" setup: setup in Rake classname="org.jruby.ant.RakeImport"/> <rakeimport/> its_in_ant: <target name="top-level" depends="its_in_rake" ant: its_in_ant [echo] /> <target name="its_in_ant"> its_in_rake: it's in Rake <echo message="ant: its_in_ant"/> </target> </project> task :its_in_rake => [:setup, :its_in_ant] do puts "it's in Rake" end task :setup do puts "setup in Rake" end Wednesday, November 16, 11
  • 78. Rake tasks as Ant targets Buildfile: build.xml <project name="foobar" default="top-level" basedir="."> [rakeimport] (in /tmp/example2) <description>Builds, tests, and runs foobar.</description> <taskdef name="rakeimport" setup: setup in Rake classname="org.jruby.ant.RakeImport"/> <rakeimport/> its_in_ant: <target name="top-level" depends="its_in_rake" ant: its_in_ant [echo] /> <target name="its_in_ant"> its_in_rake: it's in Rake <echo message="ant: its_in_ant"/> </target> </project> top-level: BUILD SUCCESSFUL task :its_in_rake => [:setup, :its_in_ant] time: 7 seconds Total do puts "it's in Rake" end task :setup do puts "setup in Rake" end Wednesday, November 16, 11
  • 79. More… http://bit.ly/rake_ant Wednesday, November 16, 11
  • 80. Maven and RubyGems Wednesday, November 16, 11
  • 81. JRuby via Maven • Group ID: org.jruby • Artifact IDs: jruby, jruby-complete <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.jruby</groupId> <artifactId>jruby</artifactId> <version>1.6.5</version> </dependency> </dependencies> Wednesday, November 16, 11
  • 82. Maven artifacts as gems jruby -S gem install mvn:org.clojure:clojure maven Wednesday, November 16, 11
  • 83. Maven artifacts as gems jruby -S gem install mvn:org.clojure:clojure group ID Wednesday, November 16, 11
  • 84. Maven artifacts as gems jruby -S gem install mvn:org.clojure:clojure artifact ID Wednesday, November 16, 11
  • 85. Maven artifacts as gems jruby -S gem install mvn:org.clojure:clojure Successfully installed mvn:org.clojure:clojure-1.4.0.a.2-java 1 gem installed Some restrictions apply Wednesday, November 16, 11
  • 86. Maven artifacts as gems $ jruby -S irb irb(main):001:0> require 'mvn:org.clojure:clojure' => true irb(main):002:0> java_import Java::clojure.lang.PersistentHashMap => Java::ClojureLang::PersistentHashMap irb(main):003:0> phm = PersistentHashMap.create({:a => 100, :b => 200, :c => 300}) => {:c=>300, :a=>100, :b=>200} irb(main):004:0> phm.delete_if {|k,v| k == :b} Java::JavaLang::UnsupportedOperationException: from clojure.lang.APersistentMap.remove(APersistentMap.java:273) from org.jruby.java.proxies.MapJavaProxy $RubyHashMap.internalDelete(MapJavaProxy.java:154) from org.jruby.RubyHash.delete(RubyHash.java:1407) from org.jruby.RubyHash$22.visit(RubyHash.java:1464) from org.jruby.java.proxies.MapJavaProxy $RubyHashMap.visitAll(MapJavaProxy.java:182) ⋮ Wednesday, November 16, 11
  • 87. Foreign Function Interface Calling native functions Wednesday, November 16, 11
  • 88. Gamma function ∞ Γ(z) = ∫ t 0 z-1e-1 dt Wednesday, November 16, 11
  • 89. Apache Commons? org.apache.commons.math.special Class Gamma java.lang.Object org.apache.commons.math.special.Gamma public class Gamma extends java.lang.Object This is a utility class that provides computation methods related to the Gamma family of functions. Version: $Id: Gamma.java 1131229 2011-06-03 20:49:25Z luc $ Wednesday, November 16, 11
  • 90. Apache Commons? org.apache.commons.math.special Class Gamma ize ? java.lang.Object e org.apache.commons.math.special.Gamma s Rs public class Gamma en extends java.lang.Object Lic This is a utility class that provides computation methods related JA to the Gamma family of functions. Version: $Id: Gamma.java 1131229 2011-06-03 20:49:25Z luc $ Wednesday, November 16, 11
  • 91. for the coe cients in the series and estimate the error. After the Read academic paper our new formula with some classical results. The numerical comp equal number of ’correction’ terms the new formula is the most acc recommended for computing the Gamma function for large real arg Theorem 1. Let x 1, unction every n then for 1, the following express ( x) f or the !!x r sion f n 1 X Gk 2⇡ expan x ptotic (x) = + Rn (x) 1 Neme s , New asym G ˝ ergo e x2k x 8 er 7, 200 05 k=0 ecemb t h08.0 D sl2ma 7/ 0.324 wherex.don.o = O d R i (x) rg/1 1 x2n and the Gk coe cients are given by - // ap http: otic series ter ract re as ympt with bet - Abst , St -De Moiv a new one se of Stir irling erted into X wit h tho nd turns Y 1 ✓ k B2r ◆mr ation n is conv pared than 0.5 a rior to sform G = io k com s tran ma funct formula is ts greater ically sup ed up e , U serie m n sing a to the Ga The new al argume rms, num on has tu maxi- er rn m ! 2r (2r 1)r atio n ertie s. for re n’ te m1 ,m2 ,...,msk( 0 al ima ti ing’ r=1 p roxim nce prop amanujan ’correctio 2m p+4mer+...+2kmu =2k p rox rd Stirl r or eq e f rm a 1 e co nverg lace and R number o closed-fo d as 3rd o nts great to which 2 k Lap ual t, a goo ume e [7] ling, be, for eq side benefi about as al arg n older on or re o ut to em. As a ich is an 1e-10 f ersion th of a where B denotes the r th si all of the analy r rmall g o s wh er th s ne xtend ed v Bernoulli number [4]. Moreover, if x n durin elative err article is a mainder. r s e mum Note: thi te of the r ! ). a to 10 the estim 8e1/5 the ⇣ n ⌘2 adds n for a it |Rn (x)|  mptot+expxpeci+ormu ed (n ic 1) li t f ansio l 2n n w as y an e mnr(2n pa 1) (2⇡) x uctio nt a n e e give of, we co for Introd se pre ct, we ual than one. W ro the p n shows tha t hly 1 esult nr a abstr r or eq . After pariso is hig Wednesday, November 16, 11 1 i e ma in the ate error com and i t
  • 92. …and implement if (Double.isNaN(x)) { value = Double.NaN; return; } double int_part = (int) x; sign = (int_part % 2 == 0 && (x - int_part) != 0.0 && (x < 0)) ? -1 : 1 ! if ((x - int_part) == 0.0 && 0 < int_part && int_part <= FACTORIAL.leng value = Math.log(FACTORIAL[(int) int_part - 1]); d } r else if (x < 10) { double rising_factorial = 1; a for (int i = 0; i < (int) Math.abs(x) - int_part + 10; i++) { rising_factorial *= (x + i); H } NemesLogGamma l = new NemesLogGamma(x + (int) Math.abs(x) - int_par value = l.value - Math.log(Math.abs(rising_factorial)); } else { double temp = 0.0; for (int i = 0; i < NEMES_GAMMA_COEFF.length; i++) { temp += NEMES_GAMMA_COEFF[i] * 1.0 / Math.pow(x, i); } value = x * (Math.log(x) - 1 + Math.log(temp)) + (Math.log(2) + Math.log(Math.PI) - Math.log(x)) / 2.0; } Wednesday, November 16, 11
  • 93. man… man gamma Wednesday, November 16, 11
  • 94. Not reinventing the wheel TGAMMA(3) BSD Library Functions Manual TGAMMA(3) NAME tgamma, lgamma, gamma -- gamma and log of gamma SYNOPSIS #include <math.h> double tgamma(double x); ⋮ DESCRIPTION tgamma() calculates the gamma function of x. lgamma() calculates the natural logorithm of the absolute value of the gamma function of x. gamma() is the same function as tgamma. Its use is deprecated. ⋮ Wednesday, November 16, 11
  • 95. JNI Workflow javah Example.java Example.h cc gamma.c libgamma.dylib javac Example.class $ java Example Wednesday, November 16, 11
  • 96. Example.java import java.util.*; class Example { native static double gamma(double x); static { System.loadLibrary("gamma"); } public static void main(String args[]) { System.out.println(gamma(0.5)); } } Wednesday, November 16, 11
  • 97. Example.h /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Example */ #ifndef _Included_Example #define _Included_Example #ifdef __cplusplus extern "C" { #endif /* * Class: Example * Method: gamma * Signature: (D)D */ JNIEXPORT jdouble JNICALL Java_Example_gamma (JNIEnv *, jclass, jdouble); #ifdef __cplusplus } #endif #endif Wednesday, November 16, 11
  • 98. gamma.c #include "Example.h" #include <math.h> JNIEXPORT jdouble JNICALL Java_Example_gamma(JNIEnv* env, jclass jclass, jdouble jdbl) { return tgamma(jdbl); } Wednesday, November 16, 11
  • 99. Voilà! $ javah Example.java $ javac Example.java $ gcc -shared gamma.c -o libgamma.dylib -I /Library/Java/JavaVirtualMachines/1.6.0_29-b11-397.jdk/ Contents/Headers/ $ java Example 1.772453850905516 Wednesday, November 16, 11
  • 100. gamma.rb require 'ffi' module Gamma extend FFI::Library ffi_lib FFI::Library::LIBC attach_function :tgamma, [:double], :double end puts Gamma::tgamma(0.5) Wednesday, November 16, 11
  • 101. Same result*! $ jruby gamma.rb 1.77245385090552 $ jruby --1.9 -e 'p Math::gamma(0.5)' 1.77245385090552 Wednesday, November 16, 11
  • 102. Benchmark $ jruby --1.9 bench_gamma.rb Rehearsal ---------------------------------------------------------------- pure_java 3.432000 0.000000 3.432000 ( 3.432000) JNI 0.409000 0.000000 0.409000 ( 0.409000) FFI 0.281000 0.000000 0.281000 ( 0.281000) -------------------------------------------------------- total: 4.122000sec user system total real pure_java 2.849000 0.000000 2.849000 ( 2.849000) JNI 0.288000 0.000000 0.288000 ( 0.289000) FFI 0.219000 0.000000 0.219000 ( 0.219000) Wednesday, November 16, 11
  • 103. But… d y? I n ut a b o ha t W h0p://www.flickr.com/photos/evablue/5665409533/ Wednesday, November 16, 11
  • 104. Invokedynamic! • Only mainstream alternative JVM language • Worked closely with Hotspot team • JRuby master/1.7 • Waiting for Java 1.7.0u2 release • What does it mean for you? Wednesday, November 16, 11
  • 105. Benchmark Times faster than Ruby 1.9.3 16 14.2x 12 8 7.4x 5.5x 4.4x 4 2.7x 3.6x 3.5x 3.2x 1.7x 1.8x 1.6x 1.9x 0 fib +calls +consts +both richardsredblack JRuby on Java 6 JRuby on invokedynamic Wednesday, November 16, 11
  • 106. Benchmark 0.300 0.225 0.150 0.075 0 currentTimeMillis Thread#name No indy With indy Wednesday, November 16, 11
  • 107. Indy TODOs • Remaining invocation paths –varargs, super, all Java paths • Per-type specialization –Faster block-receiving calls –Faster module methods • More code in Ruby! Wednesday, November 16, 11
  • 108. Thank you! • Twitter: @hiro_asari • Github: BanzaiMan – Code examples: • jtestr-example • jni-gamma • test_example_deepthought • http://github.com/jruby/jruby http://www.engineyard.com/tryjruby Wednesday, November 16, 11
  • 109. References • http://ruby-lang.org • http://jruby.org • http://pragprog.com/book/jruby/using-jruby • http://rubyonrails.org • http://torquebox.org • http://tomcat.apache.org • http://jetty.codehause.org • http://glassfish.java.net • https://www.relishapp.com/rspec • http://cukes.info Wednesday, November 16, 11
  • 110. References • http://jtestr.codehaus.org/ • http://www.ebyte.it/library/docs/math07/ GammaApproximation.html • http://download.oracle.com/javase/6/docs/ technotes/guides/jni/ • http://jcp.org/en/jsr/detail?id=292 Wednesday, November 16, 11