SlideShare ist ein Scribd-Unternehmen logo
1 von 33
Downloaden Sie, um offline zu lesen
現実世界のJRuby
      (ショートバージョン)
       日本JRubyユーザ会 中村浩士
      @nahi nahi@ruby-lang.org
      https://github.com/nahi

ロングバージョン: http://bit.ly/RealWorldJRubyJa
自己紹介

ネットワークセキュリティ関連のシステム開発
 C/C++ (18年)、Java (13年)、Ruby (13年)

余暇のOSS開発
 CRuby (8年) とJRuby (2年) のコミッタ
 soap4r、httpclient他の開発
JRubyとは - http://jruby.org/

最新リリース版は1.6.7

JVM上で動作するRuby(動的型言語)

Open Source (CPL, GPL, LGPL)

開発開始から10年
日本でのJRuby




@yokolet @nahi @koichiroo
JRubyコミッタ3人

日本JRubyユーザ会:
http://bit.ly/JRubyUsersJp
昨年度の勉強会実施実績: 0回
本日のゴール

Java開発者、他のJVM言語利用者向け

RubyとJRubyについて学ぶ

JRubyはどんなところで使われている?
Rubyの特徴

人に優しい文法

豊富なメタプログラミング機能

高い生産性

Ruby on Rails + githubの存在
Rubyツアー 1/8: クラス定義
public class Circle extends Shape {          class Circle < Shape
  private final int radius;                    def initialize(radius)
  public Circle(int radius) {                    @radius = radius
    this.radius = radius;                      end
  }                                            attr_reader :radius
  public int getRadius() {                     def area
    return radius;                               Math::PI * (@radius ** 2)
  }                                            end
  public double getArea() {                  end
    return Math.PI * Math.pow(radius, 2);    puts Circle.new(2).area
  }
  public static void main(String[] args) {
    double area = new Circle(2).getArea();   extends → <
                                             継承は単一継承
    System.out.println(area);
  }
}

   メソッド定義 → def
   コンストラクタ → initialize
Rubyツアー 2/8: インスタンス変数
public class Circle extends Shape {          class Circle < Shape
  private final int radius;                    def initialize(radius)
  public Circle(int radius) {                    @radius = radius
    this.radius = radius;                      end
  }                                            attr_reader :radius
  public int getRadius() {                     def area
    return radius;                               Math::PI * (@radius ** 2)
  }                                            end
  public double getArea() {                  end
    return Math.PI * Math.pow(radius, 2);    puts Circle.new(2).area
  }
  public static void main(String[] args) {
    double area = new Circle(2).getArea();   this → @
    System.out.println(area);
  }
}

   attr_readerはアクセサメソッド定義用メソッド
Rubyツアー 3/8: 動的型付け
public class Circle extends Shape {          class Circle < Shape
  private final int radius;                    def initialize(radius)
  public Circle(int radius) {                    @radius = radius
    this.radius = radius;                      end
  }                                            attr_reader :radius
  public int getRadius() {                     def area
    return radius;                               Math::PI * (@radius ** 2)
  }                                            end
  public double getArea() {                  end
    return Math.PI * Math.pow(radius, 2);    puts Circle.new(2).area
  }
  public static void main(String[] args) {
    double area = new Circle(2).getArea();   変数に型なし
    System.out.println(area);
  }                                          duck-typing
}

   引数の型・数の違いによるメソッドoverloadなし
Rubyツアー 4/8: 全てが値を持つ
public class Circle extends Shape {          class Circle < Shape
  private final int radius;                    def initialize(radius)
  public Circle(int radius) {                    @radius = radius
    this.radius = radius;                      end
  }                                            attr_reader :radius
  public int getRadius() {                     def area
    return radius;                               Math::PI * (@radius ** 2)
  }                                            end
  public double getArea() {                  end
    return Math.PI * Math.pow(radius, 2);    puts Circle.new(2).area
  }
  public static void main(String[] args) {
    double area = new Circle(2).getArea();   return不要
  }
    System.out.println(area);
                                             文の値は最後の式
}
Rubyツアー 5/8:
  全てがオブジェクト、全てがメソッド
public class Circle extends Shape {          class Circle < Shape
  private final int radius;                    def initialize(radius)
  public Circle(int radius) {                    @radius = radius
    this.radius = radius;                      end
  }                                            attr_reader :radius
  public int getRadius() {                     def area
    return radius;                               Math::PI * (@radius ** 2)
  }                                            end
  public double getArea() {                  end
    return Math.PI * Math.pow(radius, 2);    puts Circle.new(2).area
  }
  public static void main(String[] args) {
    double area = new Circle(2).getArea();   Circle: 定数
    System.out.println(area);
  }                                          a*2 == a.*(2)
}

   Circle.new:
    クラスオブジェクトのnewメソッドを呼び出す
Rubyツアー 6/8: ブロック(クロージャ)
      def aaa(name, &block)
        File.open(name) do |file|        (1) File.open用ブロック
          file.each_line do |line|
            yield line
                                         ブロック実行後に自動close
(2)       end                          (1)
        end
      end
                                         (2) each_line用ブロック
                                         1行読み込む毎に呼ばれる
      aaa('a.txt') do |line|
        p line                 (3)
      end
                                         (3) aaa用ブロック
      people.group_by { |e| e.lang }     aaa内部のyieldに呼ばれる
      button1 = ...
      label1 = ...
      button1.on_action do |event|
        label1.text = 'sending...'
      end
                                         ← その他利用例
Rubyツアー 7/8:
Mix-in、オープンクラス
module Utils
  def name                        Mix-in: 実装の継承
    self.class.name    実装         Utilsモジュールの実装を
  end
end
class Book
                                  BookクラスにMix-in
  include Utils      継承
  def say
    "Hello from #{name}"
  end
end
obj = Book.new
p obj.say #=> "Hello from Book"

class Book
                                  オープンクラス:
  def say                         Bookクラスのsayメソッド
    "I'm #{name}"
  end                             を再定義
end
p obj.say #=> "I'm Book"
Rubyツアー 8/8: フックメソッド
class Base
  @@all = []                  inherited: クラスが継承
  def self.inherited(klass)
    @@all << klass
                              された場合に、継承したクラ
  end                         スを引数に呼ばれる
end

class Sub < Base
  p @@all
                              その他: included、
end                           method_added、
class SubSub < Sub            method_removed、
  p @@all
end                           method_missing、
※@@はクラス変数の接頭辞                 const_missing等
※クラスオブジェクトのキャッシュは
 リークの元なので普通やらない
Ruby言語の特徴

動的型付け(Groovyと同様)

オブジェクト指向: 全てオブジェクト、全てメソッド

ブロック(クロージャ)の活用

メタプログラミング支援
  Mix-in、オープンクラス、各種フックメソッド
JRubyの特長

Ruby on Railsを含む100%の互換性

C言語版Rubyと同等の実行速度

高いスケーラビリティ(並行動作)

Javaとの親和性の高さ
Real-World JRuby: JRuby利用実例
Java連携 (Java -> Ruby)

Java連携 (Ruby -> Java)

Javaテスト (RSpec, JtestR)

開発支援 (Ant, Maven, Jenkins)

ウェブ開発 (JRuby on Rails)
Java連携 (Java -> Ruby)

JavaからRubyライブラリを利用
import org.jruby.embed.ScriptingContainer;
public class HelloWorld {
    public static void main(String[] args) {
        ScriptingContainer ruby = new ScriptingContainer();
        ruby.runScriptlet("puts "hello,world!"");
    }
                                           source 'http://localhost/'
}
                                          group :development do
                                            host 'localhost'
                                            port 12345
                                            reloadable true

例: 独自定義ファイル解析の                              debug true
                                          end

  DSL処理系として                               group :production do
                                            host 'www.example.com'
                                          end
Java連携 (Java -> Ruby)

例: gitdiff.rb - gitライブラリを利用し、リビジョ
ンの変更サマリを取得するRubyコード
    require 'rubygems'
    require 'git'
    def diff_summary(dir, from, to)
      diff = Git.open(dir).diff(from, to)
      diff.stats[:files].map { |file, st|
        insertions = st[:insertions] || 0
        deletions = st[:deletions] || 0
        "#{file} +#{insertions} -#{deletions}"
      }
    end
    # =>[ "src/org/jruby/Ruby.java +32 -20",
    #     "src/org/jruby/RubyArray.java +93 -17",
    #     "src/org/jruby/RubyBasicObject.java +7 -0", ...
Java連携 (Java -> Ruby)

Javaからの呼び出しと抽出
 public class GitDiff {
     public static void main(String[] args) throws Exception {
         ScriptingContainer ruby = new ScriptingContainer();
         ruby.runScriptlet("require 'gitdiff'");

        ruby.put("dir", "/home/nahi/git/jruby/");
        ruby.put("from", "8c6dba0f...");
        ruby.put("to", "7837c84a...");

        List array = (List) ruby.runScriptlet(
          "diff_summary(dir, from, to)");
        for (Object obj : array) {
            System.out.println(obj.toString());
        }
        ...
Java連携 (Ruby -> Java)

RubyからJavaの機能を利用する
Javaの対話環境としての利用も可能
 % jruby -S irb
 > require 'java'
 => true
 > ni = java.net.NetworkInterface.networkInterfaces.to_a.first
 => #<Java::JavaNet::NetworkInterface:0x4d33b92c>
 > ni.getName
 => "eth0"
 > ni.isUp
 => true
 > ni.getMtu
 => 1500
 > ni.inetAddresses.map { |addr| addr.to_s }
 => ["/fe80:0:0:0:20c:29ff:fead:4bed%2", "/192.168.96.129"]
Java連携 (Ruby -> Java)

Flying Saucerを使ってHTMLをPDF変換
http://code.google.com/p/flying-saucer/
% ls flyingsaucer-R8
core-renderer.jar iText-2.0.8.jar ...
% jruby -S irb -Iflyingsaucer-R8
> require 'java'
> require 'iText-2.0.8.jar'
> require 'core-renderer.jar'
> rr = org.xhtmlrenderer.pdf.ITextRenderer.new
> doc = <<EOD
<html><body><h1>Hello JRuby</h1>
<p>from <a href="http://code.google.com/p/flying-saucer/">Flying
Saucer</a>.</p></body></html>
EOD
> rr.set_document_from_string(doc)
> rr.layout
> File.open("out.pdf", "w") { |f| rr.create_pdf(f.to_outputstream) }
Javaテスト (RSpec)

   RubyとJRubyの利点を活かしてJavaをテスト
                               describe 'ScriptingContainer#put' do
                                 before :each do
   RSpec:                          @x = org.jruby.embed. ScriptingContainer.new
                                 end
   振る舞いをテスト                      it "sets an object to local variable" do
                                   obj = Object.new
   http://rspec.info               @x.put("var", obj)
                                   @x.run_scriptlet("var").should == obj
% jruby -S rspec jruby_spec.rb   end
..                               it "overrides the previous object" do
                                   obj = Object.new
Finished in 0.044 seconds          @x.put("var", obj)
2 examples, 0 failures             @x.put("var", nil)
%                                  @x.run_scriptlet("var").should be_nil
                                 end
                               end
Javaテスト (JtestR)

JtestR: 各種Ruby用テストライブラリ同梱
http://jtestr.codehaus.org/
   describe "X509Name" do
     it "should use given converter for ASN1 encode" do
       converter = mock(X509NameEntryConverter)
       name = X509Name.new('CN=localhost', converter)
       converter.stubs('getConvertedValue').
         with(DERObjectIdentifier.new(CN), 'localhost').
         returns(DERPrintableString.new('converted')).
         times(1)
       name.toASN1Object.to_string.should == '...'
     end
   end
Javaテスト (JtestR)

Ant/Maven統合 + テストサーバ
                               <?xml version="1.0" encoding="utf-8"?>
                               <project basedir="." default="test"
                                   name="simple1">
                                 <taskdef name="jtestr"
                                   classname="org.jtestr.ant.JtestRAntRunner"
% ant test                         classpath="build_lib/jtestr.jar" />
Buildfile: /path/to/build.xml    <taskdef name="jtestr-server"
                                   classname="org.jtestr.ant.JtestRAntServer"
test:                              classpath="build_lib/jtestr.jar" />
                                 <target name="test">
   [jtestr] Other Spec: 4 examples, 0 failures, 0 errors
   [jtestr]                        <jtestr port="20333"/>
                                 </target>
   [jtestr] Total: 4 tests, 0 failures, 0 errors, 0 pending
   [jtestr]                      <target name="test-server" >
                                   <jtestr-server port="20333" runtimes="3"/>
                                 </target>
BUILD SUCCESSFUL
                               </project>
Total time: 9 seconds
開発支援 (Ant連携)
                                 desc "Build JRuby"
Rake: Rubyの記述力                   task :build do
                                   ant "jar"
を活かして                            end
                                 task :jar => :build
ビルド手順を記述                         desc "Clean all built output"
                                 task :clean do
                                   delete_files = FileList.new do |fl|
                                     fl.
Ant、Rakeから相互                           include("#{BUILD_DIR}/**").
                                       exclude("#{BUILD_DIR}/rubyspec").
にタスクを利用可能                              include(DIST_DIR).
                                       include(API_DOCS_DIR)
                                   end
<target name=”load-rake-task”>     ...
  <taskdef name=”rake” classname=”org.jruby.ant.Rake”/>
</target>
<target name=”default” depends=”load-rake-task”>
  <rake task=”jar”/>
</target>
開発支援 (Maven連携)

Maven配布物はrubygemsとしてインストール可能

開発環境の部分的Ruby化を支援

  % jruby -S gem install bouncycastle:bcprov-jdk15

  require 'rubygems'
  require 'maven/bouncycastle/bcprov-jdk15'
  ...
開発支援 (Jenkins連携)

Ruby Plugins for Jenkins
http://bit.ly/JenkinsRuby

JenkinsのプラグインをRubyで記述可能
開発支援 (Jenkins連携)
例: Travis CI設定を読んで自動ビルド
class TravisScriptBuilder < Jenkins::Tasks::Builder
  def prebuild(build, listener)
    travis_file = build.workspace + '.travis.yml'
    unless travis_file.exist?
      listener.error "Travis config `#{travis_file}' not found"
      raise "Travis config file not found"
    end
    ...
  def perform(build, launcher, listener)
    run_scripts(setup_env)
    ...
  def run_scripts(env)
    %w{before_script script after_script}.each do |type|
      scan_multiline_scripts(config[type]).each do |script|
        launcher.execute(env, script,
          :chdir => workspace, :out => listener)
        ...
ウェブ開発 (JRuby on Rails)

Ruby on Rails - http://rubyonrails.org

  ウェブアプリケーションフレームワーク

  フルスタック

  CoC: (XML)設定より規約(に従って開発)

  DRY: 同じことを繰り返さない
ウェブ開発 (JRuby on Rails)

Railsの全ての機能 + 既存Javaライブラリ活用

Javaアプリと同居可能

SpringMVCからRailsへのリファクタリング事例
  1) "Petclinic"にJRubyでREST APIを追加
  2) Railsの同居
  3) Spring利用の機能をRailsで置き換え
http://bit.ly/refactoring-to-rails
JRuby on Railsのデプロイ

WAR形式 → 任意のJavaアプリサーバで動作

専用アプリサーバ:
 Trinidad(Tomcatベース)
    https://github.com/trinidad/trinidad
  TorqueBox(JBossベース)
    clustering、messaging、scheduling他
    http://torquebox.org/
まとめ: JRuby - http://jruby.org/

JavaとRuby両方の豊富な資産を利用可能
   38624 in search.maven.org
   36713 in rubygems.org     (as of 20120403)


現実世界で使われるフレームワーク、ライブラリ
 Rails、RSpec、JtestR、Jenkins、scripting、DSL

Java開発者のツールベルトに

Weitere ähnliche Inhalte

Was ist angesagt?

Cloud computing competition by Hapyrus
Cloud computing competition by HapyrusCloud computing competition by Hapyrus
Cloud computing competition by HapyrusKoichi Fujikawa
 
Van laarhoven lens
Van laarhoven lensVan laarhoven lens
Van laarhoven lensNaoki Aoyama
 
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01nagachika t
 
R Language Definition 2.2 to 2.3
R Language Definition 2.2 to 2.3R Language Definition 2.2 to 2.3
R Language Definition 2.2 to 2.3Kohta Ishikawa
 
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜Takeshi Arabiki
 
問合せ最適化インサイド
問合せ最適化インサイド問合せ最適化インサイド
問合せ最適化インサイドTakahiro Itagaki
 
板ポリだけで めちゃカッコいい グラフィックスを出す!
板ポリだけで めちゃカッコいい グラフィックスを出す!板ポリだけで めちゃカッコいい グラフィックスを出す!
板ポリだけで めちゃカッコいい グラフィックスを出す!notargs
 
Javaセキュアコーディングセミナー東京第1回演習の解説
Javaセキュアコーディングセミナー東京第1回演習の解説Javaセキュアコーディングセミナー東京第1回演習の解説
Javaセキュアコーディングセミナー東京第1回演習の解説JPCERT Coordination Center
 
PFDS 10.2.1 lists with efficient catenation
PFDS 10.2.1 lists with efficient catenationPFDS 10.2.1 lists with efficient catenation
PFDS 10.2.1 lists with efficient catenation昌平 村山
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Naoki Aoyama
 
イチからはじめるLuarida-マイコン
イチからはじめるLuarida-マイコンイチからはじめるLuarida-マイコン
イチからはじめるLuarida-マイコン三七男 山本
 
Chapter 6: Computing on the language (R Language Definition)
Chapter 6: Computing on the language (R Language Definition)Chapter 6: Computing on the language (R Language Definition)
Chapter 6: Computing on the language (R Language Definition)Nagi Teramo
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPUTakuro Iizuka
 
ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-
ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-
ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-uedayou
 
Kyoto Tycoon Guide in Japanese
Kyoto Tycoon Guide in JapaneseKyoto Tycoon Guide in Japanese
Kyoto Tycoon Guide in JapaneseMikio Hirabayashi
 
1.2新機能と1.2から始めるcql3
1.2新機能と1.2から始めるcql31.2新機能と1.2から始めるcql3
1.2新機能と1.2から始めるcql3seki_intheforest
 
Deep Learningと他の分類器をRで比べてみよう in Japan.R 2014
Deep Learningと他の分類器をRで比べてみよう in Japan.R 2014Deep Learningと他の分類器をRで比べてみよう in Japan.R 2014
Deep Learningと他の分類器をRで比べてみよう in Japan.R 2014Takashi J OZAKI
 

Was ist angesagt? (20)

Cloud computing competition by Hapyrus
Cloud computing competition by HapyrusCloud computing competition by Hapyrus
Cloud computing competition by Hapyrus
 
Van laarhoven lens
Van laarhoven lensVan laarhoven lens
Van laarhoven lens
 
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
 
R Language Definition 2.2 to 2.3
R Language Definition 2.2 to 2.3R Language Definition 2.2 to 2.3
R Language Definition 2.2 to 2.3
 
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
文字列カーネルによる辞書なしツイート分類 〜文字列カーネル入門〜
 
問合せ最適化インサイド
問合せ最適化インサイド問合せ最適化インサイド
問合せ最適化インサイド
 
板ポリだけで めちゃカッコいい グラフィックスを出す!
板ポリだけで めちゃカッコいい グラフィックスを出す!板ポリだけで めちゃカッコいい グラフィックスを出す!
板ポリだけで めちゃカッコいい グラフィックスを出す!
 
Javaセキュアコーディングセミナー東京第1回演習の解説
Javaセキュアコーディングセミナー東京第1回演習の解説Javaセキュアコーディングセミナー東京第1回演習の解説
Javaセキュアコーディングセミナー東京第1回演習の解説
 
PFDS 10.2.1 lists with efficient catenation
PFDS 10.2.1 lists with efficient catenationPFDS 10.2.1 lists with efficient catenation
PFDS 10.2.1 lists with efficient catenation
 
Clojure
ClojureClojure
Clojure
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術
 
イチからはじめるLuarida-マイコン
イチからはじめるLuarida-マイコンイチからはじめるLuarida-マイコン
イチからはじめるLuarida-マイコン
 
Chapter 6: Computing on the language (R Language Definition)
Chapter 6: Computing on the language (R Language Definition)Chapter 6: Computing on the language (R Language Definition)
Chapter 6: Computing on the language (R Language Definition)
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU関東GPGPU勉強会 LLVM meets GPU
関東GPGPU勉強会 LLVM meets GPU
 
C++14 Overview
C++14 OverviewC++14 Overview
C++14 Overview
 
ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-
ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-
ふぉとぶらり+LODAC -iPhoneアプリでのSPARQLでの活用事例-
 
Kyoto Tycoon Guide in Japanese
Kyoto Tycoon Guide in JapaneseKyoto Tycoon Guide in Japanese
Kyoto Tycoon Guide in Japanese
 
1.2新機能と1.2から始めるcql3
1.2新機能と1.2から始めるcql31.2新機能と1.2から始めるcql3
1.2新機能と1.2から始めるcql3
 
Deep Learningと他の分類器をRで比べてみよう in Japan.R 2014
Deep Learningと他の分類器をRで比べてみよう in Japan.R 2014Deep Learningと他の分類器をRで比べてみよう in Japan.R 2014
Deep Learningと他の分類器をRで比べてみよう in Japan.R 2014
 

Andere mochten auch

VDI - modern office of the 21st century
VDI - modern office of the 21st centuryVDI - modern office of the 21st century
VDI - modern office of the 21st centuryzeom, s.r.o.
 
Presentatie Afstudeeronderzoek
Presentatie AfstudeeronderzoekPresentatie Afstudeeronderzoek
Presentatie Afstudeeronderzoeknljvleugels
 
JavaOne Tokyo JVM言語BOF ベンチマーク JRuby
JavaOne Tokyo JVM言語BOF ベンチマーク JRubyJavaOne Tokyo JVM言語BOF ベンチマーク JRuby
JavaOne Tokyo JVM言語BOF ベンチマーク JRubyHiroshi Nakamura
 
Are You Cut Out For Consulting
Are You Cut Out For ConsultingAre You Cut Out For Consulting
Are You Cut Out For Consultingjacobs5628
 
Java SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyJava SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyHiroshi Nakamura
 
All About Schawk!
All About Schawk!All About Schawk!
All About Schawk!akhelt
 

Andere mochten auch (7)

VDI - modern office of the 21st century
VDI - modern office of the 21st centuryVDI - modern office of the 21st century
VDI - modern office of the 21st century
 
Presentatie Afstudeeronderzoek
Presentatie AfstudeeronderzoekPresentatie Afstudeeronderzoek
Presentatie Afstudeeronderzoek
 
JavaOne Tokyo JVM言語BOF ベンチマーク JRuby
JavaOne Tokyo JVM言語BOF ベンチマーク JRubyJavaOne Tokyo JVM言語BOF ベンチマーク JRuby
JavaOne Tokyo JVM言語BOF ベンチマーク JRuby
 
The Logic of Disorder
The Logic of DisorderThe Logic of Disorder
The Logic of Disorder
 
Are You Cut Out For Consulting
Are You Cut Out For ConsultingAre You Cut Out For Consulting
Are You Cut Out For Consulting
 
Java SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRubyJava SE 7 InvokeDynamic in JRuby
Java SE 7 InvokeDynamic in JRuby
 
All About Schawk!
All About Schawk!All About Schawk!
All About Schawk!
 

Ähnlich wie 現実世界のJRuby(ショートバージョン)

第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」yoshiaki iwanaga
 
Layout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてLayout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてkimukou_26 Kimukou
 
Processingによるプログラミング入門 第6回
Processingによるプログラミング入門 第6回Processingによるプログラミング入門 第6回
Processingによるプログラミング入門 第6回Ryo Suzuki
 
第2回デザインパターン資料
第2回デザインパターン資料第2回デザインパターン資料
第2回デザインパターン資料gaaupp
 
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~Fujio Kojima
 
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回Tomoya Kawanishi
 
DTrace for biginners part(2)
DTrace for biginners part(2)DTrace for biginners part(2)
DTrace for biginners part(2)Shoji Haraguchi
 
C#勉強会 ~ C#9の新機能 ~
C#勉強会 ~ C#9の新機能 ~C#勉強会 ~ C#9の新機能 ~
C#勉強会 ~ C#9の新機能 ~Fujio Kojima
 
Node-v0.12の新機能について
Node-v0.12の新機能についてNode-v0.12の新機能について
Node-v0.12の新機能についてshigeki_ohtsu
 
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoGo言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoShoot Morii
 
Ruby&Active Support for expert 3
Ruby&Active Support for expert 3Ruby&Active Support for expert 3
Ruby&Active Support for expert 3xibbar
 
Redmineプラグインのテスト自動化を頑張っている話
Redmineプラグインのテスト自動化を頑張っている話Redmineプラグインのテスト自動化を頑張っている話
Redmineプラグインのテスト自動化を頑張っている話Ko Nagase
 
ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。Kazuki Onishi
 

Ähnlich wie 現実世界のJRuby(ショートバージョン) (20)

第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」
 
Project lambda
Project lambdaProject lambda
Project lambda
 
Layout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用についてLayout analyzerでのgroovyの利用について
Layout analyzerでのgroovyの利用について
 
Processingによるプログラミング入門 第6回
Processingによるプログラミング入門 第6回Processingによるプログラミング入門 第6回
Processingによるプログラミング入門 第6回
 
Scala on Hadoop
Scala on HadoopScala on Hadoop
Scala on Hadoop
 
Boost tour 1_40_0
Boost tour 1_40_0Boost tour 1_40_0
Boost tour 1_40_0
 
第2回デザインパターン資料
第2回デザインパターン資料第2回デザインパターン資料
第2回デザインパターン資料
 
Entity Framework
Entity FrameworkEntity Framework
Entity Framework
 
Dsl&Builder
Dsl&BuilderDsl&Builder
Dsl&Builder
 
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
C#の新機能勉強会 ~ C#7、8の新機能を活用して速く安全なプログラムを書こう~
 
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回
 
DTrace for biginners part(2)
DTrace for biginners part(2)DTrace for biginners part(2)
DTrace for biginners part(2)
 
C#勉強会 ~ C#9の新機能 ~
C#勉強会 ~ C#9の新機能 ~C#勉強会 ~ C#9の新機能 ~
C#勉強会 ~ C#9の新機能 ~
 
Node-v0.12の新機能について
Node-v0.12の新機能についてNode-v0.12の新機能について
Node-v0.12の新機能について
 
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoGo言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
 
Prosym2012
Prosym2012Prosym2012
Prosym2012
 
Ruby&Active Support for expert 3
Ruby&Active Support for expert 3Ruby&Active Support for expert 3
Ruby&Active Support for expert 3
 
Redmineプラグインのテスト自動化を頑張っている話
Redmineプラグインのテスト自動化を頑張っている話Redmineプラグインのテスト自動化を頑張っている話
Redmineプラグインのテスト自動化を頑張っている話
 
Move semantics
Move semanticsMove semantics
Move semantics
 
ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。ラズパイでデバイスドライバを作ってみた。
ラズパイでデバイスドライバを作ってみた。
 

Mehr von Hiroshi Nakamura

エンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSSエンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSSHiroshi Nakamura
 
Information security programming in ruby
Information security programming in rubyInformation security programming in ruby
Information security programming in rubyHiroshi Nakamura
 
ちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvasちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvasHiroshi Nakamura
 
Ruby HTTP clients comparison
Ruby HTTP clients comparisonRuby HTTP clients comparison
Ruby HTTP clients comparisonHiroshi Nakamura
 
HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方Hiroshi Nakamura
 

Mehr von Hiroshi Nakamura (7)

エンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSSエンタープライズソフトウェア開発とOSS
エンタープライズソフトウェア開発とOSS
 
Information security programming in ruby
Information security programming in rubyInformation security programming in ruby
Information security programming in ruby
 
Embulk 20150411
Embulk 20150411Embulk 20150411
Embulk 20150411
 
ちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvasちゃんと理解するForce.com canvas
ちゃんと理解するForce.com canvas
 
Ruby HTTP clients comparison
Ruby HTTP clients comparisonRuby HTTP clients comparison
Ruby HTTP clients comparison
 
HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方HSM用ミドルウェア Conduit Toolkitの概要と使い方
HSM用ミドルウェア Conduit Toolkitの概要と使い方
 
HSM超入門講座
HSM超入門講座HSM超入門講座
HSM超入門講座
 

現実世界のJRuby(ショートバージョン)

  • 1. 現実世界のJRuby (ショートバージョン) 日本JRubyユーザ会 中村浩士 @nahi nahi@ruby-lang.org https://github.com/nahi ロングバージョン: http://bit.ly/RealWorldJRubyJa
  • 2. 自己紹介 ネットワークセキュリティ関連のシステム開発 C/C++ (18年)、Java (13年)、Ruby (13年) 余暇のOSS開発 CRuby (8年) とJRuby (2年) のコミッタ soap4r、httpclient他の開発
  • 7. Rubyツアー 1/8: クラス定義 public class Circle extends Shape { class Circle < Shape private final int radius; def initialize(radius) public Circle(int radius) { @radius = radius this.radius = radius; end } attr_reader :radius public int getRadius() { def area return radius; Math::PI * (@radius ** 2) } end public double getArea() { end return Math.PI * Math.pow(radius, 2); puts Circle.new(2).area } public static void main(String[] args) { double area = new Circle(2).getArea(); extends → < 継承は単一継承 System.out.println(area); } } メソッド定義 → def コンストラクタ → initialize
  • 8. Rubyツアー 2/8: インスタンス変数 public class Circle extends Shape { class Circle < Shape private final int radius; def initialize(radius) public Circle(int radius) { @radius = radius this.radius = radius; end } attr_reader :radius public int getRadius() { def area return radius; Math::PI * (@radius ** 2) } end public double getArea() { end return Math.PI * Math.pow(radius, 2); puts Circle.new(2).area } public static void main(String[] args) { double area = new Circle(2).getArea(); this → @ System.out.println(area); } } attr_readerはアクセサメソッド定義用メソッド
  • 9. Rubyツアー 3/8: 動的型付け public class Circle extends Shape { class Circle < Shape private final int radius; def initialize(radius) public Circle(int radius) { @radius = radius this.radius = radius; end } attr_reader :radius public int getRadius() { def area return radius; Math::PI * (@radius ** 2) } end public double getArea() { end return Math.PI * Math.pow(radius, 2); puts Circle.new(2).area } public static void main(String[] args) { double area = new Circle(2).getArea(); 変数に型なし System.out.println(area); } duck-typing } 引数の型・数の違いによるメソッドoverloadなし
  • 10. Rubyツアー 4/8: 全てが値を持つ public class Circle extends Shape { class Circle < Shape private final int radius; def initialize(radius) public Circle(int radius) { @radius = radius this.radius = radius; end } attr_reader :radius public int getRadius() { def area return radius; Math::PI * (@radius ** 2) } end public double getArea() { end return Math.PI * Math.pow(radius, 2); puts Circle.new(2).area } public static void main(String[] args) { double area = new Circle(2).getArea(); return不要 } System.out.println(area); 文の値は最後の式 }
  • 11. Rubyツアー 5/8: 全てがオブジェクト、全てがメソッド public class Circle extends Shape { class Circle < Shape private final int radius; def initialize(radius) public Circle(int radius) { @radius = radius this.radius = radius; end } attr_reader :radius public int getRadius() { def area return radius; Math::PI * (@radius ** 2) } end public double getArea() { end return Math.PI * Math.pow(radius, 2); puts Circle.new(2).area } public static void main(String[] args) { double area = new Circle(2).getArea(); Circle: 定数 System.out.println(area); } a*2 == a.*(2) } Circle.new: クラスオブジェクトのnewメソッドを呼び出す
  • 12. Rubyツアー 6/8: ブロック(クロージャ) def aaa(name, &block) File.open(name) do |file| (1) File.open用ブロック file.each_line do |line| yield line ブロック実行後に自動close (2) end (1) end end (2) each_line用ブロック 1行読み込む毎に呼ばれる aaa('a.txt') do |line| p line (3) end (3) aaa用ブロック people.group_by { |e| e.lang } aaa内部のyieldに呼ばれる button1 = ... label1 = ... button1.on_action do |event| label1.text = 'sending...' end ← その他利用例
  • 13. Rubyツアー 7/8: Mix-in、オープンクラス module Utils def name Mix-in: 実装の継承 self.class.name 実装 Utilsモジュールの実装を end end class Book BookクラスにMix-in include Utils 継承 def say "Hello from #{name}" end end obj = Book.new p obj.say #=> "Hello from Book" class Book オープンクラス: def say Bookクラスのsayメソッド "I'm #{name}" end を再定義 end p obj.say #=> "I'm Book"
  • 14. Rubyツアー 8/8: フックメソッド class Base @@all = [] inherited: クラスが継承 def self.inherited(klass) @@all << klass された場合に、継承したクラ end スを引数に呼ばれる end class Sub < Base p @@all その他: included、 end method_added、 class SubSub < Sub method_removed、 p @@all end method_missing、 ※@@はクラス変数の接頭辞 const_missing等 ※クラスオブジェクトのキャッシュは リークの元なので普通やらない
  • 17. Real-World JRuby: JRuby利用実例 Java連携 (Java -> Ruby) Java連携 (Ruby -> Java) Javaテスト (RSpec, JtestR) 開発支援 (Ant, Maven, Jenkins) ウェブ開発 (JRuby on Rails)
  • 18. Java連携 (Java -> Ruby) JavaからRubyライブラリを利用 import org.jruby.embed.ScriptingContainer; public class HelloWorld { public static void main(String[] args) { ScriptingContainer ruby = new ScriptingContainer(); ruby.runScriptlet("puts "hello,world!""); } source 'http://localhost/' } group :development do host 'localhost' port 12345 reloadable true 例: 独自定義ファイル解析の debug true end DSL処理系として group :production do host 'www.example.com' end
  • 19. Java連携 (Java -> Ruby) 例: gitdiff.rb - gitライブラリを利用し、リビジョ ンの変更サマリを取得するRubyコード require 'rubygems' require 'git' def diff_summary(dir, from, to) diff = Git.open(dir).diff(from, to) diff.stats[:files].map { |file, st| insertions = st[:insertions] || 0 deletions = st[:deletions] || 0 "#{file} +#{insertions} -#{deletions}" } end # =>[ "src/org/jruby/Ruby.java +32 -20", # "src/org/jruby/RubyArray.java +93 -17", # "src/org/jruby/RubyBasicObject.java +7 -0", ...
  • 20. Java連携 (Java -> Ruby) Javaからの呼び出しと抽出 public class GitDiff { public static void main(String[] args) throws Exception { ScriptingContainer ruby = new ScriptingContainer(); ruby.runScriptlet("require 'gitdiff'"); ruby.put("dir", "/home/nahi/git/jruby/"); ruby.put("from", "8c6dba0f..."); ruby.put("to", "7837c84a..."); List array = (List) ruby.runScriptlet( "diff_summary(dir, from, to)"); for (Object obj : array) { System.out.println(obj.toString()); } ...
  • 21. Java連携 (Ruby -> Java) RubyからJavaの機能を利用する Javaの対話環境としての利用も可能 % jruby -S irb > require 'java' => true > ni = java.net.NetworkInterface.networkInterfaces.to_a.first => #<Java::JavaNet::NetworkInterface:0x4d33b92c> > ni.getName => "eth0" > ni.isUp => true > ni.getMtu => 1500 > ni.inetAddresses.map { |addr| addr.to_s } => ["/fe80:0:0:0:20c:29ff:fead:4bed%2", "/192.168.96.129"]
  • 22. Java連携 (Ruby -> Java) Flying Saucerを使ってHTMLをPDF変換 http://code.google.com/p/flying-saucer/ % ls flyingsaucer-R8 core-renderer.jar iText-2.0.8.jar ... % jruby -S irb -Iflyingsaucer-R8 > require 'java' > require 'iText-2.0.8.jar' > require 'core-renderer.jar' > rr = org.xhtmlrenderer.pdf.ITextRenderer.new > doc = <<EOD <html><body><h1>Hello JRuby</h1> <p>from <a href="http://code.google.com/p/flying-saucer/">Flying Saucer</a>.</p></body></html> EOD > rr.set_document_from_string(doc) > rr.layout > File.open("out.pdf", "w") { |f| rr.create_pdf(f.to_outputstream) }
  • 23. Javaテスト (RSpec) RubyとJRubyの利点を活かしてJavaをテスト describe 'ScriptingContainer#put' do before :each do RSpec: @x = org.jruby.embed. ScriptingContainer.new end 振る舞いをテスト it "sets an object to local variable" do obj = Object.new http://rspec.info @x.put("var", obj) @x.run_scriptlet("var").should == obj % jruby -S rspec jruby_spec.rb end .. it "overrides the previous object" do obj = Object.new Finished in 0.044 seconds @x.put("var", obj) 2 examples, 0 failures @x.put("var", nil) % @x.run_scriptlet("var").should be_nil end end
  • 24. Javaテスト (JtestR) JtestR: 各種Ruby用テストライブラリ同梱 http://jtestr.codehaus.org/ describe "X509Name" do it "should use given converter for ASN1 encode" do converter = mock(X509NameEntryConverter) name = X509Name.new('CN=localhost', converter) converter.stubs('getConvertedValue'). with(DERObjectIdentifier.new(CN), 'localhost'). returns(DERPrintableString.new('converted')). times(1) name.toASN1Object.to_string.should == '...' end end
  • 25. Javaテスト (JtestR) Ant/Maven統合 + テストサーバ <?xml version="1.0" encoding="utf-8"?> <project basedir="." default="test" name="simple1"> <taskdef name="jtestr" classname="org.jtestr.ant.JtestRAntRunner" % ant test classpath="build_lib/jtestr.jar" /> Buildfile: /path/to/build.xml <taskdef name="jtestr-server" classname="org.jtestr.ant.JtestRAntServer" test: classpath="build_lib/jtestr.jar" /> <target name="test"> [jtestr] Other Spec: 4 examples, 0 failures, 0 errors [jtestr] <jtestr port="20333"/> </target> [jtestr] Total: 4 tests, 0 failures, 0 errors, 0 pending [jtestr] <target name="test-server" > <jtestr-server port="20333" runtimes="3"/> </target> BUILD SUCCESSFUL </project> Total time: 9 seconds
  • 26. 開発支援 (Ant連携) desc "Build JRuby" Rake: Rubyの記述力 task :build do ant "jar" を活かして end task :jar => :build ビルド手順を記述 desc "Clean all built output" task :clean do delete_files = FileList.new do |fl| fl. Ant、Rakeから相互 include("#{BUILD_DIR}/**"). exclude("#{BUILD_DIR}/rubyspec"). にタスクを利用可能 include(DIST_DIR). include(API_DOCS_DIR) end <target name=”load-rake-task”> ... <taskdef name=”rake” classname=”org.jruby.ant.Rake”/> </target> <target name=”default” depends=”load-rake-task”> <rake task=”jar”/> </target>
  • 27. 開発支援 (Maven連携) Maven配布物はrubygemsとしてインストール可能 開発環境の部分的Ruby化を支援 % jruby -S gem install bouncycastle:bcprov-jdk15 require 'rubygems' require 'maven/bouncycastle/bcprov-jdk15' ...
  • 28. 開発支援 (Jenkins連携) Ruby Plugins for Jenkins http://bit.ly/JenkinsRuby JenkinsのプラグインをRubyで記述可能
  • 29. 開発支援 (Jenkins連携) 例: Travis CI設定を読んで自動ビルド class TravisScriptBuilder < Jenkins::Tasks::Builder def prebuild(build, listener) travis_file = build.workspace + '.travis.yml' unless travis_file.exist? listener.error "Travis config `#{travis_file}' not found" raise "Travis config file not found" end ... def perform(build, launcher, listener) run_scripts(setup_env) ... def run_scripts(env) %w{before_script script after_script}.each do |type| scan_multiline_scripts(config[type]).each do |script| launcher.execute(env, script, :chdir => workspace, :out => listener) ...
  • 30. ウェブ開発 (JRuby on Rails) Ruby on Rails - http://rubyonrails.org ウェブアプリケーションフレームワーク フルスタック CoC: (XML)設定より規約(に従って開発) DRY: 同じことを繰り返さない
  • 31. ウェブ開発 (JRuby on Rails) Railsの全ての機能 + 既存Javaライブラリ活用 Javaアプリと同居可能 SpringMVCからRailsへのリファクタリング事例 1) "Petclinic"にJRubyでREST APIを追加 2) Railsの同居 3) Spring利用の機能をRailsで置き換え http://bit.ly/refactoring-to-rails
  • 32. JRuby on Railsのデプロイ WAR形式 → 任意のJavaアプリサーバで動作 専用アプリサーバ: Trinidad(Tomcatベース) https://github.com/trinidad/trinidad TorqueBox(JBossベース) clustering、messaging、scheduling他 http://torquebox.org/
  • 33. まとめ: JRuby - http://jruby.org/ JavaとRuby両方の豊富な資産を利用可能 38624 in search.maven.org 36713 in rubygems.org (as of 20120403) 現実世界で使われるフレームワーク、ライブラリ Rails、RSpec、JtestR、Jenkins、scripting、DSL Java開発者のツールベルトに