safe navigation operator in ruby

24
try! から .? へ (#11537) Powered by Rabbit 2.1.8 try! から .? へ (#11537) 表参道.rb#6 東京糸井重⾥事務所さま 2015-11-04 伊藤 浩⼀ (@koic) (株)永和システムマネジメント

Upload: koichi-ito

Post on 14-Jan-2017

2.586 views

Category:

Engineering


6 download

TRANSCRIPT

Page 1: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

try!�から�.?�へ(#11537)

表参道.rb#6東京糸井重⾥事務所さま

2015-11-04

伊藤�浩⼀�(@koic)(株)永和システムマネジメント

Page 2: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

About�Me

Page 3: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

Come�and�Join�Us

Page 4: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

Today's�Topic

Safe�navigation�operator✓

Ruby�2.3.0�に⼊る有⼒な�

Language�Changes�のひとつ最新の情報は�https://bugs.ruby-lang.org�などをご参照ください

[2015.11.06追記]�まだ議論中の内容を取り扱っており、記法など変わる可能性があります

Page 5: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

2.3.0-dev

Page 6: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

Safe�navigation�

operator

obj.?foo�という呼び出し⽅で、Active�Support�の�try!�に似た振る舞いをするobj.try!�{}�相当のブロック付き呼び出しはできないなど違いはある

.�のバリエーションとしての�.?�と捉えると良さそう

Page 7: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

Other�Languages

Groovy�や�Swift,�C#�6.0�に相当の機能があるらしい�(風聞)

他の⾔語の�?.�と�.?�は似ている?

Ruby�ではメソッド名の最後に�?�を付けられるため�?.�は使えず�?.他の⾔語と逆なので注意✓

Page 8: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

どう書く?

上がActive�Supportのtry!で、下がSafe�navigation�operator

������������������

������������

Page 9: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

Railsむかし話

Safe�navigation�operator�の振る舞いは�try!�の⽅に似てるRails�4�で�try�の動きが変わって�

try!�が導⼊されている✓

Rails�3�の�try�をアンラーニングされず�(?)�、名残りで�try�を使っているコードをちらほら

Page 10: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

try�と�try!�(Rails�3)

try!�メソッドはそもそも存在せず

��������������������������

�������������������������������������

�����������������������������������������������������������������������������������������������������

���������������������������������������������������������������������������������������

���������������������������������������������������������������������������������������

Page 11: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

try�と�try!�(Rails�4)

try�メソッドの振る舞いは変わる

�������������������������

�������������������������������������

��������������������������������������

��������������������������������������

������������������������������������������������������������������������������������������������������

Page 12: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

Safe�navigation�

operator

Rails�3�の�try�あるいは�Rails�4�の�try!�に似た感じになる

������������������������

��������������������������������

������������������������������������������������������������������������������������������������

Page 13: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

Active�Support�による�

try�のおさらい

Rails�4�での�Active�Support�のコードを⾒てみましょう

Page 14: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

Rails�4�での�try�の実装

��������������������������������������������������������������������

Page 15: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

try�の実装を⾒て

条件に⼀致しない場合は�nil�が返る。つまり�respond̲to?�に反応するメソッドがなければ�

nil�が返る

つまりレシーバに対応するメソッドがあってもなくても動く

それを期待していることはあまりないのでは?

Page 16: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

Rails�4�での�try!�の実装

������������������������������������������������������������������������������������������������������������������������������������������������������������

Page 17: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

try!�の実装を⾒て

try�と異なり�respond̲to?�は⾒ていないので、メソッドがなければエラーになる

Page 18: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

あれ?(⼀瞬分からなくなる)

try!�はレシーバに存在しないメソッド呼び出しをしたらエラーになる

nil�への対応のはずなのに、nil�にないメソッドを呼んだらエラーになるよね?

Page 19: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

Method#source̲location�を使った解析

メソッドの定義場所が違うらしい

���������������������������������������������������������������������������������������

��������������������������������������������������������������������������������������

Page 20: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

nil�専用の�try�実装

try.rb�にレシーバ�nil�専用の振る舞いがある

������������������������������������������

��������������������������������

Page 21: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

まとめ

上がActive�Supportのtry!で、下がSafe�navigation�operator

������������������

������������

Page 22: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

考えられる移⾏

期待しているメソッドが存在している前提で戻り値が�nil�の場合を想定しているケースにおいて、大体の場合は�try�ではなく�try!�が良さそう

obj.try!(:foo)�で良い場所は�

obj.?foo�に置き換えてけそう✓

Page 23: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

Safe�navigation�

operator�を試してみよう

�����������������������

Page 24: Safe navigation operator in Ruby

try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8

To�be�continued...

https://bugs.ruby-lang.org/issues/11537

https://github.com/ruby/ruby

https://github.com/rails/rails