Download pdf - Ruby2.0 Getting Started

Transcript
Page 1: Ruby2.0 Getting Started

Ruby2.0 Getting Started Ruby2.0をはじめよう!

Page 2: Ruby2.0 Getting Started

Agenda

• Ruby2.0について

•新機能紹介

•非互換性

•パフォーマンス

Page 3: Ruby2.0 Getting Started

About Ruby2.0

About Ruby2.0 Ruby2.0について

Page 4: Ruby2.0 Getting Started

About Ruby2.0

• 2013年2月24日にリリース( Ruby20歳の誕生日! )

• Ruby1.9との高い互換性

• 数多くの新機能

• パフォーマンスの向上

• 2.0.0は「安定版」リリース

• 「Rubyは言語として2.0でほぼ完成」by matz

Page 5: Ruby2.0 Getting Started

Future

Future 新機能紹介

Page 6: Ruby2.0 Getting Started

Future

• キーワード引数

• Enumerable#lazy

• Module#prepend

• シンボルリストリテラル

• Refinments

• その他

Page 7: Ruby2.0 Getting Started

Keyword Arguments Future

Keyword Arguments キーワード引数

Page 8: Ruby2.0 Getting Started

Keyword Arguments Future

def hello(options = {})

# デフォルト値を適用

options = {name: "guest"}.merge(options)

puts "Hello #{options[:name]}!!"

end

hello #=> Hello guest!!

hello(name: "taro") #=> Hello taro!!

~1.9でも実現可能

Page 9: Ruby2.0 Getting Started

Keyword Arguments Future

def hello(name: "guest")

puts "Hello #{name}!!"

end

hello #=> Hello guest!!

hello(name: "taro") #=> Hello taro!!

2.0ではこうなる

Page 10: Ruby2.0 Getting Started

Keyword Arguments Future

# Ruby1.9

def hello(options = {})

options = {name: "guest"}.merge(options)

puts "Hello #{options[:name]}!!"

end

シンプルに書けるようになった!

# Ruby2.0

def hello(name: "guest")

puts "Hello #{name}!!"

end

Page 11: Ruby2.0 Getting Started

Keyword Arguments Future

def hello(name: "guest")

puts "Hello #{name}!!"

end

hello(nama: "jiro") #=> ArgumentError: unknown keyword: nama

引数の存在チェックもしてくれる

Page 12: Ruby2.0 Getting Started

Keyword Arguments Future

def hello(name: "guest", **options)

msg = "Hello #{name}!!"

msg.upcase! if options[:upcase]

puts msg

end

hello(name: "hanako") #=> Hello hanako!!

hello(name: "hanako", upcase: true) #=> HELLO HANAKO!!

**で残りのHashを受け取れる

Page 13: Ruby2.0 Getting Started

Keyword Arguments Future

def foo(somehash, option: 1)

# do something...

end

# 引数の最後がHashの場合、キーワードだと判断される

hash_arg = {name: "guest"}

foo(hash_arg) #=> ArgumentError: unknown keyword: name

# オプションとして空のHashを指定することで回避可能

foo(hash_arg, {})

最後の引数がHashのメソッドは注意

Page 14: Ruby2.0 Getting Started

Keyword Arguments Future

• オプションパラメータを受けるメソッドがシンプルに実装できる

• 引数の存在チェックもしてくれる

• 引数の最後にHashを受ける場合は使わない

積極的に使うべき!!

Page 15: Ruby2.0 Getting Started

Enumerable#lazy Future

Enumerable#lazy 遅延評価イテレータ

Page 16: Ruby2.0 Getting Started

Enumerable#lazy Future

• 遅延評価を行うEnumeratorを返すメソッド

• 遅延評価=必要とされるまで評価(実行)しない

• selectやmapの利用範囲が広がる

• 巨大なリストの処理が省メモリに

Enumerable#lazyって?

Page 17: Ruby2.0 Getting Started

Enumerable#lazy Future

# lazy不使用:なかなか結果が返ってこない

(1..100000000).select{|num| num.odd?}.take(5)

#=> [1, 3, 5, 7, 9]

# lazy使用:すぐに結果が返ってくる

(1..100000000).lazy.select{|num| num.odd?}.take(5).force

#=> [1, 3, 5, 7, 9]

1~1億の奇数を5個取り出してみる

Page 18: Ruby2.0 Getting Started

Enumerable#lazy Future

• IO・Range・巨大な配列を省メモリに処理

• 無限リストでselectやmapを使う

• Railsアプリでは使い所は少ないかも

• 続きはWEBで

http://www.techscore.com/tech/Ruby/ruby-2.0/lazy/

Enumerable#lazyの使い道

Page 19: Ruby2.0 Getting Started

Module#prepend Future

Module#prepend モジュールによるオーバーライド

Page 20: Ruby2.0 Getting Started

Module#prepend Future

• Module#includeの親戚

• includeは自クラスと親クラスの間にモジュールを挿入

• prependは自クラスの手前にモジュールを追加

• 対象クラスのメソッドをオーバーライド可能に

Module#prependって?

Page 21: Ruby2.0 Getting Started

Module#prepend Future

module IM

def hoge; puts "IM#hoge"; end

end

module PM

def hoge; puts "PM#hoge"; super; end

end

class C

include IM

prepend PM

def hoge; puts " C#hoge"; super; end

end

prependとincludeの比較 - 1

Page 22: Ruby2.0 Getting Started

Module#prepend Future

# ancestorsで継承階層を表示する

C.ancestors #=> [PM, C, IM, Object, Kernel, BasicObject]

obj = C.new

obj.hoge

# PM#hoge

# C#hoge

# IM#hoge

prependとincludeの比較 - 2

Page 23: Ruby2.0 Getting Started

Module#prepend Future

• 構造化された再利用可能なモンキーパッチ

• alias_method_chain(ActiveSupport)の撲滅

• RailsやActiveRecordなど、既存のライブラリを拡張するライブラリを制作する時に便利!

Module#prependの使い道

Page 24: Ruby2.0 Getting Started

Symbol list literal Future

Symbol list literal シンボルリストリテラル

Page 25: Ruby2.0 Getting Started

Symbol list literal Future

# 普通に配列リテラルで書く

[:hoge, :fuga, :piyo] #=>[:hoge, :fuga, :piyo]

# %wしてmapする

%w(hoge fuga piyo).map(&:intern) #=>[:hoge, :fuga, :piyo]

# シンボルリストリテラル - %i (式展開なし)

%i(hoge fuga piyo) #=>[:hoge, :fuga, :piyo]

# シンボルリストリテラル - %I (式展開あり)

%I(a#{1+1} a#{1+2}) #=>[:a2, :a3]

%i %I でシンボルの配列に。便利!!

Page 26: Ruby2.0 Getting Started

Refinements Future

Refinements 局所的なメソッド再定義

Page 27: Ruby2.0 Getting Started

Refinements Future

• 局所的に特定のクラスのメソッドを変更する仕組

• Ruby2.0の目玉機能になる筈だった

• 例)ActiveRecord+Refinments

Refinementsって?

# gem activerecord-refinements

# 以下はUser.where(name: "matz")と同じ

User.where{:name == "matz"}

Page 28: Ruby2.0 Getting Started

Refinements Future

• 残念ながら大幅に機能削減された挙句、

experimental(実験的)機能になってしまった

• 本来の想定どおりに実装されるとDSLの可能性が大きく広がる

• 2013年クリスマス頃に予定されているRuby2.1に大いに期待!!

しかし…

Page 29: Ruby2.0 Getting Started

Others Future

Others その他の新機能

Page 30: Ruby2.0 Getting Started

Others Future

• デフォルトの文字コードがUTF-8に

(マジックコメントが不要になる)

• __dir__メソッド

(実行中ファイルのディレクトリパス)

• to_hメソッド( Hashへの型変換)

• Enumerable#size(遅延サイズ評価)

• 正規表現エンジンの変更(鬼車 → 鬼雲)

• TracePointやDtraceによるデバッグ機能の強化

Page 31: Ruby2.0 Getting Started

Incompatibility

Incompatibility 非互換性

Page 32: Ruby2.0 Getting Started

Incompatibility

• iconvの削除(Ruby1.9で既に非推奨)

• IO#lines, #chars, #codepoints, #bytesがEnumeratorではなく配列を返すようになった

• Object#inspect が#to_s を呼び出さなくなった

• デフォルトのエンコーディングがUTF-8に

• ABI互換性がなくなった

(1.9の.soや.bundleを共用してはいけない)

1.9 ~ 2.0の非互換性

Page 33: Ruby2.0 Getting Started

Performance

Performance パフォーマンス

Page 34: Ruby2.0 Getting Started

Performance

• bitmap marking による GC 最適化

• メソッドディスパッチなどの VM 最適化

• 浮動小数演算の最適化

• Kernel#require の最適化

最適化によるパフォーマンス向上

Page 35: Ruby2.0 Getting Started

Performance

ベンチマーク1 - 浮動小数点演算

require 'benchmark'

puts RUBY_VERSION

puts Benchmark::CAPTION

puts Benchmark.measure {100000000.times{|i| 1.0 * i}}

user system total real

1.8.7 | 2.040000 0.000000 2.040000 ( 2.086681)

1.9.3 | 1.120000 0.000000 1.120000 ( 1.161166)

2.0.0 | 0.720000 0.000000 0.720000 ( 0.724945)

Page 36: Ruby2.0 Getting Started

Performance

ベンチマーク2 – Rails起動速度

time RAILS_ENV=production rails runner ""

user system real

1.9.3 | 0m4.104s 0m0.356s 0m4.620s

2.0.0 | 0m2.154s 0m0.365s 0m2.594s

Page 37: Ruby2.0 Getting Started

Conclusion

Conclusion まとめ

Page 38: Ruby2.0 Getting Started

Conclusion

• 魅力的な新機能

• キーワード引数・lazy・prependなど

• 1.9との高い互換性

• 殆どのコードが変更なしで動作する

• パフォーマンスの向上

• 処理速度の向上

• Railsの起動速度大幅に向上

Ruby2.0の魅力