- Ruby / Rails関連
週刊Railsウォッチ: Ruby 3.1で多重代入の評価順が変更、Stimulusコンポーネントとベストプラクティスほか(20211222後編)
こんにちは、hachi8833です。今年最後の週刊Railsウォッチ後編をお送りします。
🔗Ruby
🔗 Ruby 3.1で多重代入の評価順が変更
つっつきボイス:「Ruby 3.1のリリースノートをチェックしていて、この変更を見つけました」
#4443より
「お、obj, obj.foo = obj.foo, obj
みたいなコードはめったに書かないと思いますが、Rubyの仕様↓に書かれているとおりの挙動にするなら改修が必要ということになるんでしょうね」「左から右に評価される方がたしかに自然」
「この#4443はよく見ると11年前に立てられたものでした」「そんなに昔だったとは」「それをJeremy Evansさんが拾って実装したという流れでした↓」
「Ruby内部のスタックの動きも書かれている↓」「Jeremyさんスゴい」「修正によって多重代入のパフォーマンスが落ちるらしいけど、こういう多重代入はめったに行われないだろうから大丈夫そうかな」「多重代入の評価順で挙動が変わるようなコードはめったに書かないでしょうね」「issueを上げたmameさんなら書きそう」
self # putself
abc # send
abc, self # putself
abc, foo # send
abc, foo, 0 # putobject 0
abc, foo, 0, [bar, baz] # evaluate RHS
abc, foo, 0, [bar, baz], baz, bar # expandarray
abc, foo, 0, [bar, baz], baz, bar, abc # topn 5
abc, foo, 0, [bar, baz], baz, abc, bar # swap
abc, foo, 0, [bar, baz], baz, def= # send
abc, foo, 0, [bar, baz], baz # pop
abc, foo, 0, [bar, baz], baz, foo # topn 3
abc, foo, 0, [bar, baz], baz, foo, 0 # topn 3
abc, foo, 0, [bar, baz], baz, foo, 0, baz # topn 2
abc, foo, 0, [bar, baz], baz, []= # send
abc, foo, 0, [bar, baz], baz # pop
abc, foo, 0, [bar, baz] # pop
[bar, baz], foo, 0, [bar, baz] # setn 3
[bar, baz], foo, 0 # pop
[bar, baz], foo # pop
[bar, baz] # pop
🔗 Qeweney: 機能豊富なRuby向けHTTPリクエスト/レスポンスAPI(Ruby Weeklyより)
つっつきボイス:「Rackを改善したqeweneyというgemを作ってみたという記事だそうです」
「qeweneyの読み方がわからない😅」「この図に表わされているものを改良した感じかな↓: 図を見る限りでは、Webアプリが受けるリクエストとHTTP/1やHTTP/2のアダプタを切り離しているんでしょうね」「ふむふむ」「Rackの内部はよくわからないけど、Rackでは切り離せないんじゃないかな」
「インターフェイスは、respond
で書くあたりとかがRackと違ってますね↓」
# 同記事より
# Rack
app = ->(env) do
[
200,
{'Content-Type' => 'text/plain'},
['Hello, world!']
]
}
# Qeweney
app = ->(req) do
req.respond('Hello, world!', 'Content-Type' => 'text/plain')
end
「こちらを見るとリクエストをRackに渡すこともできるみたい↓」「Qeweneyはまだ開発途中のようですが、Rackよりもパフォーマンスを優先して作っているらしい」
# redirect to another URL
req.redirect(alternative_url)
# redirect to HTTPS
req.redirect_to_https
# serve a static file
req.serve_file(file_path)
# serve from an IO
req.serve_io(io)
# serve from a Rack app
req.serve_rack(app)
# Upgrade to arbitrary protocol
req.upgrade(protocol)
🔗 regexp_parser: 正規表現パーサー(Ruby Weeklyより)
つっつきボイス:「正規表現を解析するRuby製パーサーだそうです」「どんなふうに使うんだろう?」「こじらせて読むのがつらくなった正規表現を解読するのに使うとかかな」「あるある」
# 同リポジトリより
require 'regexp_parser'
Regexp::Scanner.scan /(ab?(cd)*[e-h]+)/ do |type, token, text, ts, te|
puts "type: #{type}, token: #{token}, text: '#{text}' [#{ts}..#{te}]"
end
# output
# type: group, token: capture, text: '(' [0..1]
# type: literal, token: literal, text: 'ab' [1..3]
# type: quantifier, token: zero_or_one, text: '?' [3..4]
# type: group, token: capture, text: '(' [4..5]
# type: literal, token: literal, text: 'cd' [5..7]
# type: group, token: close, text: ')' [7..8]
# type: quantifier, token: zero_or_more, text: '*' [8..9]
# type: set, token: open, text: '[' [9..10]
# type: set, token: range, text: 'e-h' [10..13]
# type: set, token: close, text: ']' [13..14]
# type: quantifier, token: one_or_more, text: '+' [14..15]
# type: group, token: close, text: ')' [15..16]
「そういえば正規表現を解析してくれるregex101というWebサービスがありますね↓」「これめちゃ愛用しています」「こんなのがあるんですね」
参考: regex101: build, test, and debug regex
「regex101に正規表現を入れるといい感じに解析して、リファレンスも表示してくれる」「正規表現をステップ実行できるのもありがたいです🙏」「regex101はRubyの正規表現(Onigmo)には対応していないのか...」「RubularならRubyの正規表現をチェックできますよ↓」
参考: Rubular: a Ruby regular expression editor
その他Ruby
あるでかいネストした Hash があり、JSON で表現できるくらい単純である。これを一度ファイルに出力し、また Ruby プロセスで Hash として取り出したい。このとき、Hash のロードが一番速い出力形式は何か。
— _ko1 (@_ko1) December 15, 2021
つっつきボイス:「_ko1さんのこのツイートがとても面白かった」
あと試すなら protobuf? 簡単?
— _ko1 (@_ko1) December 15, 2021
「JSONで表現可能なハッシュをRubyでシリアライズしてからデシリアライズしてハッシュとして取り込むのがどれが一番速かったかをテストしてみたら、最速はmsgpackでしたが、JSONモジュールが意外に速かったという話↓」「へ〜、JSONやるな〜」「自分はMarshalが最速だと思っていたけどそうでもないんだなと気付かされました」
# ruby 3.1.0dev (2021-12-13T05:04:19Z fix_local_tp_memor.. 7ad3e2a982) [x86_64-linux]
user system total real
JSON 4.942976 0.059088 5.002064 ( 5.002097)
msgpack 4.146010 0.039891 4.185901 ( 4.185935)
eval 13.473455 0.080030 13.553485 ( 13.553678)
Marshal 7.512279 0.110032 7.622311 ( 7.622328)
参考: module JSON
(Ruby 3.0.0 リファレンスマニュアル)
参考: module Marshal
(Ruby 3.0.0 リファレンスマニュアル)
「追加されたコメントを見ると、ファイルサイズはMarshalのが一番小さいのね↓」
$ ls h* -hl
-rw-rw-r-- 1 ko1 ko1 207K Dec 15 16:00 h.iseq
-rw-rw-r-- 1 ko1 ko1 249K Dec 15 16:00 h.json
-rw-rw-r-- 1 ko1 ko1 202K Dec 15 16:00 h.marshal
-rw-rw-r-- 1 ko1 ko1 204K Dec 15 16:00 h.msgpack
-rw-rw-r-- 1 ko1 ko1 254K Dec 15 16:00 h.rson
「お、I/OをなくすとMarshalがJSONに近づいてる↓」「iseq.dump
は遅いけどiseq.eval
は速いのも面白い」
user system total real
JSON 4.603379 0.008869 4.612248 ( 4.612306)
msgpack 4.016187 0.009970 4.026157 ( 4.026212)
eval 13.732086 0.050009 13.782095 ( 13.782156)
iseq.eval 2.844302 0.010015 2.854317 ( 2.854358)
Marshal 5.147343 0.009985 5.157328 ( 5.157333)
🔗クラウド/コンテナ/インフラ/Serverless
🔗 Google Cloud SpannerがRailsのActive Recordに対応(Publickeyより)
Link: 大規模分散DBのCloud Spannerが、RailsのActive Recordに対応。スケーラブルで高可用なRubyアプリケーションの開発が容易に - Publickey
https://t.co/AjggNFjfy5— Yukihiro Matzmotto (@yukihiro_matz) December 15, 2021
つっつきボイス:「お〜、このアダプターはGoogle公式なのがいいですね👍」「ほんとだ」「公式だとそれだけで導入しやすいんですよ」
# 同リポジトリより
development:
adapter: "spanner"
project: "<google project name>"
instance: "<google instance name>"
credentials: "<google credentails file path>"
database: "app-dev"
参考: Cloud Spanner | Google Cloud
「Active RecordからSpannerにアクセスできるということなんですね」「制約を見るとカラムでDEFAULTが使えないとあるけど、SpannerにそもそもDEFAULTがないのね」「テーブルは主キーが必須か」「Railsのadd_index
でフィールド長を指定できないらしい」「この辺はCloud Spannerからくる制約なんでしょうね」
参考: Cloud Spannerの主キーの設計. Spannerがパフォーマンスを発揮するには主キーの設計が非常に重要です。そこで… | by Toyohito Murooka | google-cloud-jp | Medium
参考: add_index
-- ActiveRecord::ConnectionAdapters::SchemaStatements
「公式なら使ってみようかなという気持ちになりますね: ちなみにoracle-enhancedアダプタ↓はよく使われていて実績もあるけど公式ではないんですよ」
🔗JavaScript
🔗 Stiumulus関連のサイト2つ
つっつきボイス:「Rails 7でStimulusが正式に導入されたので、Stimulusの情報を掲載しているサイトをいくつか見つけました」「Stimulusのコンポーネントリストと、よいStimulusの書き方ですね」「コンポーネントによってはデモサイトもあって↓、Bootstrapのコンポーネントリスト的な感じなのがなかなかよさそう👍」
参考: Stimulus Animated Number
参考: Stimulus Chartjs
「StimulusのChartjsは普通に本家Chartjsを取り入れているけどバージョンは2.9.32か: ちょうどさっき調べていたんですが、Chartjsの最新は3.6.2で、2系で書かれたチャートがAPIレベルで互換性がなくて動かなかったんですよ」「なるほど、3.xは別物な感じですね」「チャートを作り込んでからチャートライブラリで非互換が発生するとつらい😢」
参考: Chart.js | Open source HTML5 Charts for your website
「もうひとつのBetter StimulusJSは↓、Stimulusのベストプラクティスを紹介しています」「こちらは個人っぽいですね」「上のStimulusコンポーネントサイトも公式っぽく見えたけどどうやら個人っぽいかも」
ちなみに本家Stimulusのリポジトリは以下です↓。
後編は以上です。来年もTechRachoと週刊Railsウォッチをどうぞよろしくお願いします。
バックナンバー(2021年度第4四半期)
週刊Railsウォッチ: Rails 7リリース、5.2系と6.0.x系のサポート終了時期決定、localhost gemで自己署名証明書生成ほか(20211221前編)
- 20211214前編 RailsでGDPRに対応する、stateful_enum gem、rubyzip 3.0ほか
- 20211207後編 改訂2版『プロを目指す人のためのRuby入門』、『研鑽Rubyプログラミング β版』ほか
- 20211206前編 sanitize_sql_likeは重要、X-XSS-Protectionヘッダーのデフォルト変更、kredis gemほか
- 20211201後編 Railsで「Read Model」を使う、Ruby Prize 2021受賞者決定、pru gemほか
- 20211129前編 フォームヘルパーの改修、Railsの監査ログgem比較、DHHとimport-mapほか
- 20211116後編 Ruby Struct入門、書籍『進化的アーキテクチャ』、AWS Web問題集ほか
- 20211115前編 Rails 7がRuby 3.1のClass#descendantsに対応、GitHub Issue風ファイルアップローダほか
- 20211110後編 JSON.parseの機能、Opal 1.3、async gem、Linuxコマンドチートシートほか
- 20211102後編 2021年度Rubyアソシエーション開発助成、Rails REST APIレベルで楽観的ロックほか
- 20211101前編 Rails 7アセットパイプライン解説記事、ロジックをapp/operatorsで整理ほか
- 20211026後編 YJITがRuby 3.1向けにマージ、ripperのドキュメント化、crontabの罠ほか
- 20211025前編 insert_allやupsert_allのタイムスタンプ自動更新、rails/contextsにロジックを置くほか
- 20211019後編 ruby/debugをChromeでリモートデバッグ、Rubyアプリの最適化ほか
- 20211018前編 Railsリポジトリで進行中のPropshaft、inverse_ofを自動推論ほか
- 20211012後編 Ruby 3.1にYJITマージのプロポーザル、Rubyのmagic historyメソッド、JSのPartytownほか
- 20211011前編 ServerTimingミドルウェア追加、paramsで数値キーを許可、Railsで多要素認証ほか
- 20211006後編 ruby/debug 1.2.0リリース、Railsにはthorが入っている、tendejitほか
- 20211004前編 Rails 7でbyebugがruby/debugに変更、GitHub Codespacesをサポートほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。
週刊Railsウォッチについて
TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)