狠狠撸

狠狠撸Share a Scribd company logo
What's Cooking In
Ruby 2.7
2019-02-27 武者 晶紀 (@knu)
自己紹介
? 武者 晶紀 / Akinori Musha
? Twitter: https://twitter.com/knu
? GitHub: https://github.com/knu
? 株式会社マチマチ
? Rubyコミッター
? FreeBSDコミッター
? Team Nokogiri
? Huginn共同開発者
自己紹介
? 仕事(抜粋)
? シーサーブログおよびOEMサービス
? イープラス公式アプリのバックエンド
? 相席屋公式アプリのバックエンド
? ご近所SNSマチマチ ?
マチマチ
? 株式会社マチマチ
? 目黒区、学芸大学駅から徒歩2分
? 会社紹介? http://bit.ly/machimachi-intro
? 「ひらかれた、つながりのある地域社会をつくる」
? ご近所SNS & 地域情報メディア? https://machimachi.com/
? エンジニア採用中! https://www.wantedly.com/companies/machimachi-inc/projects
? マチマチを支える技術$ https://t.co/OMeh3yL8YE (Rails, React, PostgreSQL, …)
? 技術ブログ? https://tech.machimachi.com/
Rubyでの開発活動
? レポジトリ管理者
? 開発インフラ整備
? 標準ライブラリの充実
? Digestの拡張、ハッシュアルゴリズム追加
? Setの実装
? bigdecimal, syslog, ipaddr, zlibなどのインポート支援や保守
? Shellwordsに shellescape, shelljoinを実装
? Ruby 1.8.7のリリース
Rubyでの開発活動
? 組込クラスの拡張
? Array#slice!
? Enumeratorの導入, Enumerableの拡張
? each_cons, each_slice
? each_with_object
Rubyでの開発活動
? 最近は、月次のRuby開発者会議に出席して、主にRails/
Web開発者の観点からインプットしたり、自分が担当す
るライブラリをいじる活動がメインです。
Ruby 2.7に向けて
? まだ2.6が出てから2ヶ月しか経っていませんが、2.7や3.0に向けた機能開発や議
論はいろいろ進行しています。その一端でも、楽しくご紹介できたらと思います。
? ここでご紹介するのはあくまで恣意的に選んだ例に過ぎず、網羅性はありません。
? 興味のある方はNEWSファイル、Ruby開発者会議の議事録、Redmineでのチ
ケットベースの議論を追いかけましょう。
? 開発者同士の議論は非常に多相的で高文脈ですが、「いろんなことがあるんだな
あ」程度の受け取りで構いません。
? 開発陣へのフィードバックは、いろんなチャンネルを通じて気軽にどうぞ!
Twitterでつぶやくだけでも目に入るかも?
おしながき
? 入ったもの
? 新文法: obj.:meth
? 無ブロックprocの段階的廃止
? Enumerable#tally
? 却下されたもの
? 開発中?検討中の機能
? 今後のRubyの予定
obj.:meth
? obj.method(:meth) の短縮文法
? メソッドオブジェクトを取り出す
? 従来のObject#methodはメソッド呼び出しだった
? メソッドを取るためにメソッドを呼ぶ必要がある…?
いかにもRubyらしいけど…
? オーバーライドされているかもしれない?
(例: Request オブジェクト = HTTPメソッドを返す)
? ObjectでなくBasicObjectを継承したオブジェクトにはmethodメソッ
ドがない
obj.:meth
? 任意のオブジェクトに対してメソッドを取り出したいときは、クラス
からメソッドを取り出してbind & callするという 遠な手段を取る
必要があった?
?Object.instance_method(:method)?
.bind(obj)?
.call
?オブジェクトの素性を問わず、メソッドを取り出す短い記法がほしい
?いくつか案があったが、既存文法との衝突がなく、シンボル記法
からメソッドを連想しやすい「obj.:meth」に決定
obj.:meth
? たとえば、こういうコードが短く書けるように
? lines.map { |line| JSON.parse(line) }?
↓?
lines.map(&JSON.:parse)
? ただし、selfは省略できないこととした
? lines.each { |line| puts line }?
↓?
lines.each(&self.:puts)
? obj.each(&.:meth)を許してしまうと、obj.each(&:meth)と見た目が
瓜二つなのに全然違う意味になるので目に優しくない、というMatzの指摘に
よる
無ブロックprocの段階的廃止
? メソッド定義中でブロックなしのprocによってメソッドに渡ってきたブロックを
取得することができる
? def each_key?
keys.each(&proc)?
end
? procはProc.newと書いても同じ、他にlambdaもある
? block_given?でブロックが渡されたかどうかを判定でき、yieldで呼び出せ
るのと合わせて、明示的に引数を書かなくても渡されたブロックを利用できた
? この機能を廃止しようという方向になった
? 無ブロックprocとProc.newは2.7から警告、無ブロックlambdaは廃止
無ブロックprocの段階的廃止
? 背景としては、最適化や誤り検出のため、あるメソッドが
ブロックを取るのかどうかを静的に判定したい、理想的に
は引数リストで明示させたい、という動機がある
? ブロックを取らないメソッドにブロックを渡しても、メ
ソッド側でチェックしない限りエラーや警告にはなら
ない
? 使われると思ってブロックを渡したが実は使われず無
意味という誤りに気づけない、という問題
無ブロックprocの段階的廃止
? ただ、CRubyには長い間、def method(&block)とブロックを引数で
受け取るのは遅いという問題があり、熟練工は書いてくれなかった?
? yieldは、渡されたブロックを直接呼ぶ命令にコンパイルされる?
? 一方、仮引数リストに&blockと書くと、ブロックからProcオブジェク
トを生成した上で、ローカル変数に代入される?
? さらにblock.callとするとローカル変数を参照し、Procオブジェク
トに対してメソッドが呼び出される?
? 何ステップも多い…?
無ブロックprocの段階的廃止
? Ruby 2.5で、仮引数リストに&blockと書いても、実際にblockを使う
までProcオブジェクトの生成を遅延するようになった?
? 中でblock_given?とyieldを使ったまま、ブロックを取ることを仮
引数リストで表現しても性能上のペナルティがなくなった?
? Ruby 2.6で、block.callはyieldと同等の性能になった?
? ただ、callのオーバーライド有無を確認するなど面倒な実装の賜物?
? これで、明示的に&blockとblock.callを使うスタイルを推奨できるよ
うになった?
無ブロックprocの段階的廃止
? 逆に、「ブロックを取らないこと」を明示できるようにすべきか、とい
う議論も進んでいる
? 当初は、def foo(&nil)と書くことにすればいいのでは、とまと
まりかけた?
? しかし、そうすると「ブロックを取らないメソッドすべてに&nilを
入れよう」という大量のPR?が一気に押し寄せる危惧があるので取
りやめに?
? 現在は、コンパイル時の静的解析でできないか、という取り組みが試さ
れている?
無ブロックprocの段階的廃止
? ただ、superという壁が発見される
? superあるいはsuper()と書くと、何も指定していないが、
渡ってきたブロックをスーパーメソッドに渡すようになっている
? superの方は分かるが、super()の方は一体なぜ…?
? そのため、スーパーメソッドも って見ないとブロック引数を
使っているのかはわからない
? 現在も既存のユーザコードを含め調査?研究が進行中$
Enumerable#tally
? 要素を値別に数えるメソッド?
?["a", "b", "b", "c", "a", "a"].tally?
# => { "a" => 3, "b" => 2, "c" => 1 }
?SQLのGROUP BY+COUNT()のようなもの
?今まではgroup_byを使ってこんな風にせざるを得なかった処理
?["a", "b", "b", "c", "a", "a"]?
.group_by(&:itself)?
.transform_values(&:size)
Enumerable#tally
? 当初はcount_byという名前で、ブロックを取る形で提案されていた(ブロックを適
用した値で集計する)
? しかし、いくつかの難点で賛同を得られず
? 名前がいまいち: countとの対称性がない(sort_by/sort, max_by/maxな
どからの類推が効かない)
? 機能が多い: ブロックを取るのはオプショナルでは?必要ならmapしてから渡
せばいい
? シュワルツ変換したいこともあるかもしれないが、代表値をどうするか仕
様を決め難い
? tallyという名前を得て、ブロックを取らないシンプルな形で採用?
Enumerable#tally
? tallyとは数を数えて記録することで、紙や黒板に一本ずつ線を書
きながらカウントするための記号の呼称でもある(日本での
「正」にあたる記号、「卌」のような形)
? ちなみにUnicode 11で「正」とともに入りました?
https://twitter.com/ken_lunde/status/
1006532079402663936
却下されたもの
? autoloadの廃止?
? Matzはスレッドセーフティの観点から本質的に危ないのでずっと消した
い派
? Railsがconst_missingでの自動ロード機構をやめてautoloadを使う
Zeitwerkを6.0で採用、というこのタイミングではしごを外すのか?と
私の中で騒然?
? しかしRailsアプリの開発ではeager-loadingだとプロセス起動?再起動
が重すぎるのでこういう機構は必須と説得?
? 少なくともRuby 3.xの間は残す、というMatzの言質を得た?
却下されたもの
? autoloadの廃止
? その後、autoloadをより安全にするための研究と改修が進んで
いる
? http://www.a-k-r.org/d/2019-02.html#a2019_02_10
? http://www.a-k-r.org/d/2019-02.html#a2019_02_10_2
? https://bugs.ruby-lang.org/issues/15598
? https://bugs.ruby-lang.org/issues/15599
却下されたもの
? ArrayやHashも、Stringのようにデフォルトでフリーズするモードがほし
い、あるいは単項 +/- でdup/freezeしたい
? https://bugs.ruby-lang.org/issues/14680
? 「そんなにほしい?」まだ懐疑的?
? でもRubocop利用者からすると、定数配列?ハッシュに.freezeを付
けて回られる経験は苦々しい…
? いずれまたチャンスあるかも?
開発中?検討中の機能
? Begin-less (Start-less) Ranges
? https://bugs.ruby-lang.org/issues/14799
? Endless Ranges (@ary[1..])が入ったので、今度は左端側を省略したものも
入れたい
? ActiveRecordなどのDSLで便利: Product.where(price: ..1000)
? Endless Rangesも導入後にいくつか問題が発見?対処されたので、それらの
手当てが終わって落ち着いてから
? Enumerator::Yielder#to_proc
? https://bugs.ruby-lang.org/issues/15618
開発中?検討中の機能
? デフォルトブロック引数: @1, @2, …
? https://bugs.ruby-lang.org/issues/4475
? ずっと望まれている機能: numbers.map { "%02x" % @1 }
? 既存文法と衝突のない奇跡の案(@1, @2,…)に期待?
? パターンマッチ機能(case-in構文)?
? https://bugs.ruby-lang.org/issues/14912
? 強く待ち望まれてきた機能
? スクリプト言語の中では強力でRubyの強みと言われてきたが、関数型言語がメジャー
になってきた今ではちょっと見劣りする
開発中?検討中の機能
? ES6スタイルのハッシュ簡便記法(?eld punning)
? https://bugs.ruby-lang.org/issues/15236
? {?
name: name,?
type: type,?
created_at: created_at?
}?
↓?
{ name, type, created_at }?
?
などと書きたいな、という例のやつ
? MJITによるさらなる高速化
今後のRubyの予定
? 2019年3月
? 11日に開発者会議: https://bugs.ruby-lang.org/issues/15614
? Unicode 12が出たら、Ruby 2.6.xをリリース
? 2019年4月
? RubyKaigi 2019: 会期前日に開発者会議
? 新元号が発表されたらUnicode 12.1が出る
? それを待ってRuby 2.6.yをリリース
? ? 毎月開発者会議
? チャンスは毎月? https://bugs.ruby-lang.org/issues/14770
? 2019年12月
? 25日 Ruby 2.7.0リリース

More Related Content

What's Cooking In Ruby 2.7