safe navigation operator in ruby
TRANSCRIPT
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
try!�から�.?�へ(#11537)
表参道.rb#6東京糸井重⾥事務所さま
2015-11-04
伊藤�浩⼀�(@koic)(株)永和システムマネジメント
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
About�Me
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
Come�and�Join�Us
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追記]�まだ議論中の内容を取り扱っており、記法など変わる可能性があります
✓
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
2.3.0-dev
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
Safe�navigation�
operator
obj.?foo�という呼び出し⽅で、Active�Support�の�try!�に似た振る舞いをするobj.try!�{}�相当のブロック付き呼び出しはできないなど違いはある
✓
✓
.�のバリエーションとしての�.?�と捉えると良さそう
✓
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
Other�Languages
Groovy�や�Swift,�C#�6.0�に相当の機能があるらしい�(風聞)
✓
他の⾔語の�?.�と�.?�は似ている?
✓
Ruby�ではメソッド名の最後に�?�を付けられるため�?.�は使えず�?.他の⾔語と逆なので注意✓
✓
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
どう書く?
上がActive�Supportのtry!で、下がSafe�navigation�operator
✓
������������������
������������
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
Railsむかし話
Safe�navigation�operator�の振る舞いは�try!�の⽅に似てるRails�4�で�try�の動きが変わって�
try!�が導⼊されている✓
Rails�3�の�try�をアンラーニングされず�(?)�、名残りで�try�を使っているコードをちらほら
✓
✓
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
try�と�try!�(Rails�3)
try!�メソッドはそもそも存在せず
��������������������������
�������������������������������������
�����������������������������������������������������������������������������������������������������
���������������������������������������������������������������������������������������
���������������������������������������������������������������������������������������
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
try�と�try!�(Rails�4)
try�メソッドの振る舞いは変わる
�������������������������
�������������������������������������
��������������������������������������
��������������������������������������
������������������������������������������������������������������������������������������������������
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
Safe�navigation�
operator
Rails�3�の�try�あるいは�Rails�4�の�try!�に似た感じになる
������������������������
��������������������������������
������������������������������������������������������������������������������������������������
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
Active�Support�による�
try�のおさらい
Rails�4�での�Active�Support�のコードを⾒てみましょう
✓
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
Rails�4�での�try�の実装
��������������������������������������������������������������������
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
try�の実装を⾒て
条件に⼀致しない場合は�nil�が返る。つまり�respond̲to?�に反応するメソッドがなければ�
nil�が返る
✓
つまりレシーバに対応するメソッドがあってもなくても動く
✓
それを期待していることはあまりないのでは?
✓
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
Rails�4�での�try!�の実装
������������������������������������������������������������������������������������������������������������������������������������������������������������
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
try!�の実装を⾒て
try�と異なり�respond̲to?�は⾒ていないので、メソッドがなければエラーになる
✓
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
あれ?(⼀瞬分からなくなる)
try!�はレシーバに存在しないメソッド呼び出しをしたらエラーになる
✓
nil�への対応のはずなのに、nil�にないメソッドを呼んだらエラーになるよね?
✓
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
Method#source̲location�を使った解析
メソッドの定義場所が違うらしい
���������������������������������������������������������������������������������������
��������������������������������������������������������������������������������������
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
nil�専用の�try�実装
try.rb�にレシーバ�nil�専用の振る舞いがある
������������������������������������������
��������������������������������
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
まとめ
上がActive�Supportのtry!で、下がSafe�navigation�operator
✓
������������������
������������
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
考えられる移⾏
期待しているメソッドが存在している前提で戻り値が�nil�の場合を想定しているケースにおいて、大体の場合は�try�ではなく�try!�が良さそう
✓
obj.try!(:foo)�で良い場所は�
obj.?foo�に置き換えてけそう✓
try!�から�.?�へ�(#11537) Powered�by�Rabbit�2.1.8
Safe�navigation�
operator�を試してみよう
�����������������������
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
✓