Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

週刊Railsウォッチ: Ruby 3.2の正規表現高速化、Googleのosv-scannerほか(20221221後編)

こんにちは、hachi8833です。今年最後の週刊Railsウォッチ後編をお送りいたします。

2023年の週刊Railsウォッチは01/17(火)公開を予定しています。

週刊Railsウォッチについて

  • 各記事冒頭には🔗でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • お気づきの点がありましたら@hachi8833までメンションをいただければ確認・対応いたします🙏

TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)

🔗Ruby

🔗 私はいかにして高速なRubyインタプリタを開発したか(Ruby Weeklyより)


つっつきボイス:「最初気づいていませんでしたが、RubyKaigiで何度もスピーチを行ったMakarovさんの記事でした」「MakarovさんといえばMIRというRuby向け軽量JITコンパイラの作者ですね」「Red Hatの人なのか」

vnmakarov/mir - GitHub

参考: Three Ruby performance projects - RubyKaigi 2018

参考: A light weight JIT compiler project for CRuby - RubyKaigi 2019

「元記事によると、SIRという新しい動的な内部表現をMIRに取り入れたRubyを作ったそうです↓」「Rubyのベンチマークによく使われるOptCarrotがもう動いているのはすごい👍」

vnmakarov/ruby - GitHub


ruby/sirflow.svg at 7553736ffeb6a72bb94fd6204bb541ab6aee2676 · vnmakarov/ruby · GitHubより


(略)最近ShopifyのYJITコンパイラが成功したことで、私は自分の戦略を見直し、CRuby向けのMIRベースのJITコンパイラをより高速に実装する方法を見出すことができました。
How I developed a faster Ruby interpreter | Red Hat Developerより



How I developed a faster Ruby interpreter | Red Hat Developerより: OptCarrotを--optで最適化した場合のベンチマーク

mame/optcarrot - GitHub

🔗 Rubyの%記法(Ruby Weeklyより)


つっつきボイス:「以前自分も似たような記事を書いたのを思い出しました↓」「%[ship good code]のような%記法ですね」「二重引用符で囲む%Q()%()と略記できるの知らなかった」「ユースケースも載っていて読みやすい記事👍」

Ruby: パーセント記号 `%` の使い方まとめ

「Rubyの%記法は独特ですよね: %(なんちゃら)のように%の直後の囲み記号がたとえば(なら閉じは)になりますけど、ここには任意の記号が使える」「そうそう、%!なんちゃら!でも%|なんちゃら|でも%?なんちゃら?でもいいんですよね」「最初見たときは不思議感あるけど、特に正規表現の%rなんかで記号をうまく選べばエスケープを減らせるのがありがたい」

参考: %記法 -- リテラル (Ruby 3.1 リファレンスマニュアル)

🔗 Ruby 3.2に入った正規表現の高速化


つっつきボイス:「この改修すごい」「メモ化を使うことで、文字列の長さに対するマッチング時間の多くを線形にしたのか」

今回実装した最適化は、ReDoSを防ぐことを目的としたもので、多くの正規表現のマッチング時間が文字列の長さに対して線形となります。
同記事より

# 同記事より
$ ruby --version
ruby 3.2.0preview2 (2022-09-09 master 35cfc9a3bb) [arm64-darwin21]

$ time ruby -e '/^(a|a)*$/ =~ "a" * 28 + "b"'
ruby -e '/^(a|a)*$/ =~ "a" * 28 + "b"'  8.49s user 0.04s system 98% cpu 8.663 total

$ ./miniruby --version
ruby 3.2.0dev (2022-10-27T13:39:56Z recache bc59b7cc1e) [arm64-darwin21]

$ time ./miniruby -e '/^(a|a)*$/ =~ "a" * 28 + "b"'
./miniruby -e '/^(a|a)*$/ =~ "a" * 28 + "b"'  0.01s user 0.01s system 8% cpu 0.310 total

参考: メモ化 - Wikipedia

「8秒かかっていた処理が0.01秒!」「これですべてのReDoSをつぶせるわけではないにしても、かなり軽減されそうですね」「指数増加から線形増加になったのは大きい👍」

参考: 20日目: 正規表現が ReDoS 脆弱になる 3 つの経験則 | 立命館コンピュータクラブ

🔗 深掘りRubyKaigi 2022インタビュー


つっつきボイス:「先週に続いて深掘りRubyKaigi 2022インタビューです」「これも文字起こしありがたい」

参考: 深掘りRubyKaigi 2022 with ko1 & kateinoigakukun - connpass -- 終了

🔗 Pathname#joinの振る舞い


つっつきボイス:「Pathname('/foo')join('bar', '/baz')すると結果が'/baz'になるのか↓」「この挙動は知らなかった」

# 同記事より
irb(main):003:0> Pathname('/foo').join('bar', 'baz')
=> #<Pathname:/foo/bar/baz>
irb(main):004:0> Pathname('/foo').join('bar', '/baz')
=> #<Pathname:/baz>
irb(main):005:0> 

「記事によるとRubyのテストコードにはこの挙動があるということだから、一応意図した動作ということらしい」「最終的にコードは直さずにPathnameのAPIドキュメントにこの挙動を追記する形で解決したんですね」

参考: [Misc #19155] [DOC] Addion of absolute paths by nobu · Pull Request #24 · ruby/pathname
参考: class Pathname (Ruby 3.1 リファレンスマニュアル)

「記事ではPythonとGoとJavaScriptの挙動についても調べていますね」「Pythonはリストの左から順にcdするのを再現したような挙動っぽいけど、GoやJavaScriptは/を無視して相対パスとしてのみ解釈している感じ」「これは知らないとハマりそう」

後で自分でもやってみました。

# Ruby
>> require 'pathname'
=> true
>> Pathname.new('').join('/foo','bar', '/baz/asdf', 'quux', '..')
=> #<Pathname:/baz/asdf>
# Python
>>> import os
>>> os.path.join('/foo', 'bar', '/baz/asdf', 'quux', '..')
'/baz/asdf/quux/..'
// Go
package main

import (
    "fmt"
    "path"
)

func main() {
    fmt.Println(path.Join("/foo", "bar", "/baz/asdf", "quux", ".."))

}

// /foo/bar/baz/asdf
// JavaScript
> const path = require("path");
undefined
> console.log(path.join('/foo', 'bar', '/baz/asdf', 'quux', '..'));
/foo/bar/baz/asdf

🔗 その他Ruby

つっつきボイス:「kakutaniさんのアドベント記事で、直近のRuby関連イベントも紹介されています」「そういえば研鑽Rubyプログラミングのβ2も販売開始されましたね」「今なら半額で買える」

参考: 研鑽Rubyプログラミング β版 – 技術書出版と販売のラムダノート

🔗 設計・セキュリティ

🔗 osv-scanner: Google製の脆弱性スキャナ

google/osv-scanner - GitHub


つっつきボイス:「ruby-jp Slackのセキュリティチャンネルで知りました」「お、これはCIに仕込んでおくと便利そう」「このツールが利用しているOSV.devは以前扱ったことがありますね(ウォッチ20210720)」

参考: OSV.dev

「GitHubならdependabotがあるけど、これならGitLabなどの他のリポジトリでも使えるし、複数言語の脆弱性をチェックできるのがよさそう👍」

参考: Configuring Dependabot security updates (Dependabot セキュリティ アップデートの構成) - GitHub Docs
参考: Google、オープンソースプロジェクト向けに脆弱性スキャナ「OSV-Scanner」提供 | TECH+(テックプラス)

🔗 徳丸本の Docker 実習環境を M1/M2 Mac で1から構築した


つっつきボイス:「徳丸先生の本↓の実習環境がDocker化されているのを知りませんでした」「記事はその環境をM1/M2 Macで1から構築してみたんですね」「M1/M2特有の手順があるかと思ったら特になかった」「Docker化された環境なしでこの本をやったときに、途中のOWASP ZAPあたりの環境構築で詰まってしまったのを思い出しました😢」

🔗クラウド/コンテナ/インフラ/Serverless

🔗 Amazon Linux 2のサポート期限延長


つっつきボイス:「babaさんがこのニュースで喜んでましたね」

🔗言語/ツール/OS/CPU

🔗 自分に合ったコーディングフォントを選ぶ


つっつきボイス:「右と左に表示されるコーディングフォントから好きなものを選んでいく勝ち抜き戦的なサイトです」「チェックすべきは1il0Oが区別しやすいかかな」「フォントによっては日本語との相性の悪いものもあるので油断できない」「JetBrains IDEのフォント(JetBrains Mono)も入ってますね」


後編は以上です。皆さまハッピーホリデー&良いお年を!

バックナンバー(2022年度第4四半期)

週刊Railsウォッチ: RailsのRuby 3.2.0対応、ActiveSupport::Durationの暗黙の変換ほか(20221220前編)

ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。

Ruby Weekly


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。