SlideShare uma empresa Scribd logo
1 de 110
Baixar para ler offline
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

Mais conteúdo relacionado

Destaque

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
 

Destaque (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
 

Semelhante a 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
 

Semelhante a 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
 

Último

Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 

Último (20)

Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 

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