- Ruby / Rails関連
週刊Railsウォッチ(20210202後編)Ruby 3 irbのmeasureコマンド、テストを関数型言語のマインドセットで考えるほか
こんにちは、hachi8833です。
- 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
- 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
- お気づきの点がありましたら@hachi8833までメンションをいただければ確認・対応いたします🙇
TechRachoではRubyやRailsの最新情報などの記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)
⚓Ruby
⚓ Ruby 3.0 irbのmeasure
コマンド(Ruby Weeklyより)
つっつきボイス:「Ruby 3.0の新機能紹介記事です」「へ〜、irbでmeasure
コマンドを実行すると行ごとに時間を測ってくれるのか」「ストップウォッチ的な機能ですね⏱」「たしかに」
# 同記事より
irb(main)> measure
TIME is added
=> nil
irb > sleep 1
processing time: 1.000649s
=> 1
irb > 1
processing time: 0.000025s
=> 1
irb > measure :off
=> nil
参考: library irb (Ruby 3.0.0 リファレンスマニュアル)
「Ruby 3.0の新機能がてんこもりで、この機能に気づかなかった↓」
参考: Ruby 3.0.0 リリース
「お、記事によるとmeasure
コマンドにstackprof↓を指定するともっと細かく調べられるのか」「irbでこういう機能が使えるようになると、ちょっとした測定が手軽にやれて便利👍」「この辺の機能を使いこなせると強くなった気持ちになれそうですね」
「Ruby 3.0の機能なので新しい環境でしか使えませんけどね」「Ruby 3.0の新機能、がっつり調べないといけないな〜」「パターンマッチングとかもですね」
後で記事のスニペット↓を動かしてstackprofをやってみました。スニペットではさりげなくRuby 3.0のendレスメソッド定義も使っていますね。
# 同記事より
def snippet()= 10_000.times { Date.parse(Date.today.to_s).year != 2020 }
参考: 改めて整理する Ruby 3.0 に実験的に入る予定のエンドレスメソッド定義構文と右代入演算子について - Secret Garden(Instrumental)
以下は素のRuby 3.0.0でも実行できるよう、gem install stackprof activesupport
を実行し、irbでrequire 'active_support/core_ext/date'
を実行しました。
3.0.0$ ruby -v
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
3.0.0$ gem install stackprof activesupport
Fetching stackprof-0.2.16.gem
Building native extensions. This could take a while...
Successfully installed stackprof-0.2.16
Building YARD (yri) index for stackprof-0.2.16...
Done installing documentation for stackprof after 0 seconds
Fetching activesupport-6.1.1.gem
Successfully installed activesupport-6.1.1
Building YARD (yri) index for activesupport-6.1.1...
Done installing documentation for activesupport after 1 seconds
2 gems installed
3.0.0$ irb
irb(main):001:0> require 'active_support/core_ext/date'
=> true
irb(main):002:0> def snippet()= 10_000.times { Date.parse(Date.today.to_s).year != 2020 }
=> :snippet
irb(main):003:0> measure :stackprof
STACKPROF is added.
=> nil
irb(main):004:0> snippet
==================================
Mode: cpu(1000)
Samples: 34 (0.00% miss rate)
GC: 2 (5.88%)
==================================
TOTAL (pct) SAMPLES (pct) FRAME
17 (50.0%) 17 (50.0%) Regexp#match
6 (17.6%) 6 (17.6%) MatchData#begin
3 (8.8%) 3 (8.8%) Date.today
3 (8.8%) 3 (8.8%) String#gsub!
2 (5.9%) 2 (5.9%) (sweeping)
1 (2.9%) 1 (2.9%) Integer#div
29 (85.3%) 1 (2.9%) Date.parse
1 (2.9%) 1 (2.9%) String#[]=
32 (94.1%) 0 (0.0%) IRB::Context#evaluate
32 (94.1%) 0 (0.0%) IRB.init_config
32 (94.1%) 0 (0.0%) StackProf.run
32 (94.1%) 0 (0.0%) IRB::Irb#signal_status
32 (94.1%) 0 (0.0%) RubyLex#each_top_level_statement
32 (94.1%) 0 (0.0%) Kernel#loop
32 (94.1%) 0 (0.0%) Kernel#catch
32 (94.1%) 0 (0.0%) IRB::Irb#run
32 (94.1%) 0 (0.0%) IRB.start
32 (94.1%) 0 (0.0%) <top (required)>
32 (94.1%) 0 (0.0%) Kernel#load
32 (94.1%) 0 (0.0%) <main>
32 (94.1%) 0 (0.0%) <main>
32 (94.1%) 0 (0.0%) IRB::WorkSpace#evaluate
32 (94.1%) 0 (0.0%) Kernel#eval
2 (5.9%) 0 (0.0%) (garbage collection)
32 (94.1%) 0 (0.0%) <main>
32 (94.1%) 0 (0.0%) Object#snippet
32 (94.1%) 0 (0.0%) Integer#times
32 (94.1%) 0 (0.0%) IRB::Irb#eval_input
=> 10000
irb(main):005:0>
⚓ HexaPDFを最適化した話(Ruby Weeklyより)
つっつきボイス:「こちらの記事は、PDF生成に使うHexaPDF gemでTrueTypeフォントを使うと測定結果↓が妙に遅いので、ランタイムプロファイリングとメモリのプロファイリングを実行し、原因を突き止めて修正するまでをやってますね」「これは泥臭そうな作業...」
Time Memory File size hexapdf 1x 557ms 34.160KiB 452.598 hexapdf 5x 1.891ms 45.244KiB 2.258.904 hexapdf 10x 3.754ms 57.364KiB 4.517.825 hexapdf 1x ttf 634ms 33.044KiB 549.522 hexapdf 5x ttf 2.335ms 48.908KiB 2.687.124 hexapdf 10x ttf 4.693ms 63.568KiB 5.360.947 同記事より
「修正後のベンチマークはこれか↓」
Time Memory File size hexapdf 1x 572ms 34.680KiB 452.598 hexapdf 5x 1.840ms 45.352KiB 2.258.904 hexapdf 10x 3.504ms 57.464KiB 4.517.827 hexapdf 1x ttf 542ms 33.540KiB 546.390 hexapdf 5x ttf 2.099ms 43.600KiB 2.670.953 hexapdf 10x ttf 4.016ms 63.584KiB 5.328.382 同記事より
- 修正結果: Change TrueType subsetter to avoid generating characters that need to… · gettalong/hexapdf@cdb8723
「Rubyコードが遅い原因を突き止めて解決するまでの泥臭くてつらい作業をまとめた、いい記事だと思います👍」「こういう作業をやれる人がチームにいるかどうかで、チームの限界性能が変わってきますよね」「たしかに」
「この記事ではHexaPDFの文字glyphを処理する周辺の効率化を行っているみたい」「つくづく、プログラマーはいろんなことを知らないといけないんだなと改めて思いますね」「PDFの仕様を以前読んだことありますけど、あれはホントわからない」「ホントに😆」
参考: TrueType - Wikipedia
参考: PDFテクノロジーセンター | Adobe PDFテクノロジーセンター -- PDF仕様などが置かれています
⚓ 関数型言語のマインドセットでオブジェクトをテストする(Ruby Weeklyより)
つっつきボイス:「thoughtbotさんの記事を久しぶりにご紹介します」「この記事はタイトルからして、テストの視点をどこに置くかという話のようですね」「意外と短いかも」
「テストに関する記事を書こうとすると、『どういう視点でテストすべきか』『どういう実装方法でテストを実装するか』など考慮すべきことが増えてきて、いわゆる『風呂敷を閉じられない』状態になりがちなのですが、この記事は1つの視点に絞って短くまとめているのが良さそうですね👍」
「お、この記事でfunctionalって言ってるのはどうやら関数型言語のことみたい」「あの難しそうなヤツですか」「ということは、記事で言っているside effect(副作用)も関数型言語における副作用を指すようです」「あ、そういうことか」「このあたりの話は、関数型言語をわかっている人ならもうわかってるのかもしれませんね」
参考: 関数型言語 - Wikipedia
参考: 副作用 (プログラム) - Wikipedia
「それにしても関数型言語が出てくるとは」「mindsetとあるのは関数型言語のマインドセットなのか」「そういう視点でテストを書くということでしょうね: テストの粒度とかテストを書くときの視点って、一般的に説明しようとすると抽象度が上がりがちで、わかったような気がするけど結局わからなかったということになりがちなんですが、『関数型言語の副作用のようなものだ』という視点を持ち込むことで、ある種のテストの書き方を理解しやすくしようという意図をこの記事に感じました」「なるほど」「もちろんテストの書き方の視点はひとつではなく、これ以外にもいろいろあります」
「ところで、副作用というとちょっとネガティブなイメージありますよね」「あるある」
参考: 副作用 - Wikipedia
🔗 その他Ruby
your downvotes only fuel me
— Nate Berkopec (@nateberkopec) January 26, 2021
つっつきボイス:「RubyのWebサーバーPumaのメンテナをやっているNate Berkopecさんのツイートが気になったので拾ってみました」
「スレッドがこのツイートから始まっているのでそれ以前の文脈はわかりませんが、『あなたはActive Supportのpresent?
やblank?
を普段から使いすぎているか』というような話かな?」「自分はそう思いました: present?
やblank?
を乱用するってどういうことなのかが気になりました」
「Active Supportのpresent?
やblank?
は、どういう使い方をするかにもよるんですが、かの有名な『PHPの==
による比較』↓に少し通じるところがあるんですよ」「あ、PHPですか」「そういえばJavaScriptの==
と===
も意味が違ってたかも」「JavaScriptの==
も厳密でない比較ですね」
参考: 条件式の「==」と「===」の意味と違いの3つのポイント | PLUGMIZE(プラグマイズ)
参考: JavaScript 忘れがちな === と == の違い - Qiita
「よく考えてみると、present?
やblank?
って、存在するのは何なのか、空白なのは何なのかが実はファジーじゃないですか: 調べる対象は文字列の空文字(""
)かもしれないし、数値のゼロ(0
)かもしれない」「あ〜!」「nil
かもしれないですよね」
「present?
やblank?
は元のオブジェクトが何であってもチェックできるのでとても便利なんですが、空文字かどうかを調べるならString#empty?
がありますし、数値がゼロかどうかを調べるならNumeric#zero?
がありますし、nil
かどうかを調べるにはnil?
で調べるべきでしょうね」「う、心当たりが😅」
「上のツイートは、『本来そうやってチェックすべき箇所をblank?
とかで雑にチェックしてる人はまさかいないよね?』ぐらいの意味合いなんだろうなと自分は受け止めました」「なるほど、ちょっと腑に落ちてきました」
「ちょうどNateさんのツイートの続きにこんなのもあった↓、まさにtruthy/falselyしか気にしてない人、つまりtrueっぽければそれでいい、falseっぽければそれで済ませるという人には、present?
やblank?
をそうやって雑に使って欲しくないということなんでしょうね」「Nateさんの気持ちがちょっと見えてきたかも」
Just don’t use them if all you really care about is truthy/falsely
— Nate Berkopec (@nateberkopec) January 26, 2021
「とりあえずのノリでpresent?
やblank?
を使ってくれるなよと」「わかってて使うならいいけど、わかってないうちに使ってくれるなよと」「overuseって言ってるのはそういうことなんでしょうね」
「でも自分は作り捨てのコードなら割と使っちゃいますけどね😆」「😆」「でもpresent?
もblank?
もActive Supportのメソッドなので、たまに素のRubyで使おうとしたら『あ、Active Support入れないと使えないんだった』と思い出したりということもありましたね」
- API:
Object#present?
- API:
Object#blank?
⚓クラウド/コンテナ/インフラ/Serverless
⚓ sudoに脆弱性が見つかる
つっつきボイス:「BPSの社内Slackに貼っていただいた情報です」「上の脆弱性情報記事、今日見てみたら情報が更新されてる: ありがたい!」
「sudoの脆弱性はLinux OSの"ほぼ"すべてが対象なのがキツい」「Dockerコンテナのようにコンテナ化されたLinuxは、コンテナにsudoが入ってなければ影響はありません」
参考: sudo - Wikipedia
「それにしても久しぶりに影響の大きい脆弱性ですね」「だいぶ前にbashで起きた脆弱性以来かも↓」「ありましたね、bashの脆弱性」
参考: 更新:bash の脆弱性対策について(CVE-2014-6271 等):IPA 独立行政法人 情報処理推進機構 -- 2014年の情報です
「まだ詳しく見ていないんですが、今回のsudo脆弱性はsudoのコンフィグを変えて対処できる感じではなさそうなんですよ: と思ったら上の脆弱性情報記事にちょうど書いてあった↓」「バイナリをリネームですって」「脆弱なsudo実行バイナリがユーザーから実行可能な場所にある限り起きちゃうんですね...」
CentOS6を使用されている場合には、
sudoを使えないようにする(バイナリをリネームする等)
が、現時点での緩和策では一番確実だと思われます。
同記事より
「おそらく今回の脆弱性は、sudoをアップデートせずに回避するのが難しそうです: 特定の機能に潜む脆弱性ならコンフィグでその機能を無効にすることで基本的に回避できますが、上の脆弱性情報記事を見る限りではsudoをユーザー権限で実行できさえすれば攻撃できてしまうように見えますね」「う〜む」「これはエグい」
「それにしては比較的世の中が静かなよう見えますが、今後どこかのタイミングで急に騒がしくなるかもしれませんね」「情報出てから24時間ぐらいしか経ってないからかなと思ったら、数日経ってるんですね」「sudoの脆弱性は今後も見守っておきたいです」
⚓JavaScript
⚓ mongoose: Node.js向けMongoDBクライアント&ライブラリ
つっつきボイス:「こういうのがあると知人から教わりました」「Node.jsでMongoDBを扱う、こういうのは前からありそうかな」「バージョン5とあるぐらいだから前からあるんでしょうね」「よく見ると★も異様に多い」
参考: The most popular database for modern apps | MongoDB
以下はつっつき後に見つけたツイートです。
あとは mongoose モジュールが便利https://t.co/7OMSlMidSKhttps://t.co/iAr5SSRyiq pic.twitter.com/NKqElYK0Lm
— ダーパ局長 (@darpakyokutyou) June 21, 2020
⚓言語/ツール/OS/CPU
⚓ 言語は継続
GitHubからcloneした各種プログラミング言語のソースをコレクションしている。そのほとんどが過去1年更新がなくて停滞している。継続重要
— Yukihiro Matz (@yukihiro_matz) January 21, 2021
つっつきボイス:「各種プログラミング言語のソースをコレクションですか」「さすが言語を愛する人」「私が手伝っているGoby言語↓も恥ずかしながら開店休業に近い状態です😅」
後編は以上です。
バックナンバー(2021年度第1四半期)
週刊Railsウォッチ(20210201前編)Webpackerのガイドがマージ、RailsはRuby 3でどのぐらい速くなったかほか
- 20210126後編 Google Cloud FunctionsがRubyをサポート、Ruby 3のパターンマッチングでポーカーゲームほか
- 20210125前編 Railsリポジトリのデフォルトブランチがmainに変更、Rails 6.1はMySQLのENUM型に対応済みほか
- 20210120後編 Ruby 3.0の新機能で遊ぶ、RubyスニペットをJSに変換するRuby2JS、rspec-parameterized gemほか
- 20210113後編 Ruby 3.0 Ractor解説記事、Vercelホスティングサービス、教育用OS xv6ほか
- 20210112前編 Active Recordの範囲指定バリデーション改善、soleとfind_sole_byメソッド、AlgoliaとRailsほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。