- Ruby / Rails関連
週刊Railsウォッチ: JRubyが9.4.0.0でRuby 3.1に対応、IRB v1.5.0リリースほか(20221207後編)
こんにちは、hachi8833です。土曜日に第12回中高生国際Rubyプログラミングコンテストの最終審査会を見に三鷹産業プラザまで行ってまいりました。受賞者の皆さんおめでとうございます!🎉 今回はMatz賞が2本も出ました(Matz賞は出ない年もあるそうです)。
参考: 中高生国際Rubyプログラミングコンテスト in Mitaka
参考: 「中高生国際Rubyプログラミングコンテスト2022 in Mitaka」 受賞者が決定いたしました! | 中高生国際Rubyプログラミングコンテスト in Mitaka
先日開催された「中高生国際Rubyプログラミングコンテスト」で弊社ソニックガーデンからソニックガーデン賞を選定させてもらいました!
「うんうん、こういうwebアプリ作っていくのいいよね、楽しいよね!」という共感ポイントの高いwebアプリでした。のぞみさん、おめでとうございます!🎉 #IRPC https://t.co/xm7dLk7f3z— Junichi Ito (伊藤淳一) (@jnchito) December 5, 2022
中高生国際 #Ruby プログラミングコンテスト (#IRPC) の現地会場に来ました!! 💎✨
協賛企業が多すぎて1枚の写真に収まりきらない...!!! 😳📸
IRPC 2022 - つくりたい! が世界を変えていく!https://t.co/mUdXiE25kv https://t.co/ovaLO4Vp6x pic.twitter.com/rhaZ1yHYCh
— 安川要平/Yohei Yasukawa (@yasulab) December 3, 2022
🔗Ruby
🔗 IRB v1.5.0リリース(Ruby Weeklyより)
`edit` opens a file with the editor command defined with `ENV["EDITOR"]`
- `edit` - opens the file the current context belongs to (if applicable)
- `edit Foo` - opens the file of Foo
- `edit https://t.co/XZTbn1vYY8` - opens the file of https://t.co/XZTbn1vYY8 pic.twitter.com/ZK8aNT3RWZ— Stan Lo @[email protected] (@_st0012) November 21, 2022
なお現時点の最新バージョンはv1.5.1です。
つっつきボイス:「ruby/debugでおなじみのst0012さんのツイートです」「お〜、irbでedit
コマンドが使えるとは!」「カレントのコンテキストにあればそのファイルを開くんですね」「さすがに実行中のファイルはロードし直さないと反映されないかな?」
「しかもedit Foo
でFooのファイルをエディタで開いたり、edit Foo.bar
みたいに特定のメソッドを指定するとFooのbar定義箇所にカーソルが合った状態で開けたりするんですね」「これは賢い👍」
🔗 オブジェクトシェイプのマージとYJITの最適化
- PR: Implement Object Shapes by jemmaissroff · Pull Request #6386 · ruby/ruby
- issue: Feature #18776: Object Shapes - Ruby master - Ruby Issue Tracking System
YJIT is now optimized to take advantage of object shapes. [[Feature #18776]]
ruby/NEWS.md at master · ruby/ruby · GitHubより
# #6386より
class Foo
def initialize
# Starts with shape id 0
@a = 1 # transitions to shape id 1
@b = 1 # transitions to shape id 2
end
end
class Bar
def initialize
# Starts with shape id 0
@a = 1 # transitions to shape id 1
@b = 1 # transitions to shape id 2
end
end
foo = Foo.new # `foo` has shape id 2
bar = Bar.new # `bar` has shape id 2
つっつきボイス:「少し前のニュースですが、CRuby向けのオブジェクトシェイプがマージされていた↓ことを最近知りました」「RubyKaigi 2022で発表された後まもなくだから9月末ぐらいですね」
参考: Implementing Object Shapes in CRuby - RubyKaigi 2022
「オブジェクトシェイプだからRuby内部のVMに関連するということですね: ユーザーコードでは特に何もしなくていい高速化」「RubyVM::Shape
というものが追加されたようなので、これを使ってシェイプを調べたりできそう」
参考: class RubyVM::Shape
- RDoc Documentation -- 3.2.0.preview3
「オブジェクトシェイプの件に気づいたのは、もともとM1 MacbookでYJITをコンパイルしようとしてあれこれやっていたときに、YJITがx86_64に加えてarm64(M1チップ)でもオブジェクトシェイプの最適化が進んでいるらしいことに気づいた↓のがきっかけでした↓」
参考: ruby/yjit/src/asm/x86_64 at master · ruby/ruby · GitHub
参考: ruby/yjit/src/asm/arm64 at master · ruby/ruby · GitHub
「ついでに、以下はM1 Macbookで3.2.0-devのパフォーマンスをとりあえずbenchmark-driverで3.1.2と2.6.8と雑に比較してみたものですが、結果がよかったものを恣意的にピックアップしたのでベンチマークとは言えないヤツです😆」「そうしたい気持ちわかる😆」
# M1で3.2.0-devのYJITを有効にした場合の比較
$ ruby general_attr_accessor_vs_getter_and_setter.rb
Benchmark general_attr_accessor_vs_getter_and_setter.rb
Warming up --------------------------------------
slow 6.354M i/s - 6.415M times in 1.009678s (157.38ns/i)
fast 7.154M i/s - 7.261M times in 1.014869s (139.78ns/i)
Calculating -------------------------------------
2.6.8 3.1.2 3.2.0-dev
slow 7.370M 7.411M 10.032M i/s - 19.062M times in 2.586581s 2.572160s 1.900036s
fast 8.266M 8.143M 9.638M i/s - 21.462M times in 2.596360s 2.635542s 2.226854s
Comparison:
slow
3.2.0-dev: 10032424.1 i/s
3.1.2: 7410879.2 i/s - 1.35x slower
2.6.8: 7369561.2 i/s - 1.36x slower
fast
3.2.0-dev: 9638007.3 i/s
2.6.8: 8266355.6 i/s - 1.17x slower
3.1.2: 8143461.6 i/s - 1.18x slower
なお、後でやってみたところ、M1 Macbook環境で自分がビルドしたRuby 3.2.0-devではRubyVM::Shape
クラスがまだ有効になりませんでした😢。ビルドログにはcompiling ../shape.c
があるのですが。
$ ~/.rubies/ruby-master/bin/ruby -v
ruby 3.2.0dev (2022-12-06T02:52:34Z master 53473f8ea9) +YJIT [arm64-darwin22]
$ ~/.rubies/ruby-master/bin/irb
>> defined?(RubyVM::YJIT)
#=> "constant"
>> defined?(RubyVM::Shape)
#=> nil
参考: class RubyVM
(Ruby 3.1 リファレンスマニュアル)
Ruby の 内部情報へのアクセス手段を提供するクラスです。デバッグ用、プロトタイピング用、研究用などのとても限定された用途向けです。一般ユーザーは使うべきではありません。
classRubyVM
(Ruby 3.1 リファレンスマニュアル)より
🔗 JRubyが9.4.0.0リリースでRuby 3.1に対応(Ruby Weeklyより)
It's a Thanksgiving miracle: JRuby 9.4 is released! We've made a huge leap forward, now supporting Ruby 3.1 compatibility and Rails 7. Nearly all of the major features of 2.7, 3.0, and 3.1 are included. Give it a try and let us know if you run into issues!https://t.co/YYbt3d84CJ
— JRuby Dev Team (@jruby) November 23, 2022
つっつきボイス:「JRubyがRuby 3.1をキャッチアップしたのはすごい🎉」「以前のJRubyはRuby 2.6対応だったから、かなり大きなアップグレード」「それをやりきったのはマジすごいですね」「今年1月のウォッチにJRubyの人からアップグレード作業中と返信いただいたのを思い出しました↓(ウォッチ20220118)」「JRubyが活発に活動していることがよくわかる👍」
Thank you for the mention of JRuby's 20th anniversary! Just FYI, the next version of JRuby, 9.4, will be compatible with Ruby 3.0 at least, and we are getting close to release time. Hopefully available before Ruby 2.6 is EOL in March.
— Charles Oliver Nutter @[email protected] (@headius) January 23, 2022
「お、JRubyトップページのバナー表示がまだ"Ruby 2.6 compatible"のままですね」「ホントだ」「まだWebサイトまでは更新が追いついていない感じですね」
後でJRubyの中の人にお知らせいたしました↓。
Oh good call!
— Charles Oliver Nutter @[email protected] (@headius) December 2, 2022
🔗 git blame
でRuboCopの自動変更を非表示にする方法(Ruby Weeklyより)
つっつきボイス:「短い記事です」「gitにこのコンフィグを設定して、git blame
で無視して欲しいコミットを.git-blame-ignore-revsファイルに書き込んで配置すれば、git blame
時に当該コミットをスキップした上で履歴を見ることができるのか」
# 同記事より
git config blame.ignoreRevsFile .git-blame-ignore-revs
「GitHubのドキュメントを見ると、.git-blame-ignore-revsファイルにこんな感じで書けばいいらしい↓」「gitの機能なんですね」
# docs.github.comより
# .git-blame-ignore-revs
# Removed semi-colons from the entire codebase
a8940f7fbddf7fad9d7d50014d4e8d46baf30592
# Converted all JavaScript to TypeScript
69d029cec8337c616552756310748c4a507bd75a
参考: Viewing a file - GitHub Docs
「CI環境でrubocop -a
のようなツールで自動修正を行わせていると、git blame
したときに人間でないユーザーのコミットが最終コミットとして表示されて邪魔になったりするんですが、そういう問題を解消するということですね👍」「たしかにgit blame
しても誰の修正かすぐにわからなくて困ることってありますよね」
🔗 module_function
はextend self
と同じなのか?
- 元記事: Is module_function really the same as extend self? | by Tech - RubyCademy | RubyCademy | Medium
つっつきボイス:「このextend self
っていう書き方見たことなかった↓」「何これ?!」「うはっ」
# 同記事より: extend self
module RubyCademy
extend self
def headline
puts "Learn Ruby and Ruby on Rails!"
end
end
RubyCademy.headline # => Learn Ruby and Ruby on Rails!
# 同記事より: module_function
module RubyCademy
def headline
puts "Learn Ruby and Ruby on Rails!"
end
module_function :headline
end
RubyCademy.headline # => Learn Ruby and Ruby on Rails!
「Rubyのモジュールはクラスではないのでheadline
メソッドをそのままでは呼び出せないんですよね: それがextend self
することでRubyCademy.headline
のように呼び出せるようになる、と」「ここだけ見ればmodule_function
みたいな動作ですね」
参考: class Module
(Ruby 3.1 リファレンスマニュアル)
参考: Module#module_function
(Ruby 3.1 リファレンスマニュアル)
「おさらいすると、Rubyのモジュールは基本的にinclude
して使うことが前提で、そのままだとモジュールのメソッドは呼び出せない」「そうそう」「逆に、include
しないでモジュールのまま使う前提の場合は、module_function
で特別にモジュールのメソッドを直接呼び出せるようにするのが常道ですね(同じモジュールをinclude
して普通のモジュールとして使うこともできます)」
「ところで、RubyCademy.headline
という呼び出しの形は一見クラスメソッドっぽいけど、上のRubyCademyはモジュールだからクラスメソッドとは呼ばないんですよね」「そうそう、かといってモジュールメソッドという言葉もないんですよ」「ややこしい」「モジュールの特異メソッドと呼ぶのがいいのかな」
「実はRubyでクラスメソッドと呼ばれているものも、その実体はあくまでクラスの特異メソッドなんですよ」「そういえばそうでした」
参考: 特異メソッド定義 -- クラス/メソッドの定義 (Ruby 3.1 リファレンスマニュアル)
「それにしてもextend self
という書き方はちょっとびっくり」「上のコードを見ると、extend self
する場合はモジュール内のメソッドをまとめて全部アクセス可能にできるんですね」「逆にmodule_function
はメソッドを名指しで個別に指定しないといけないのか」
「個別に指定する方がよさそうですけどね」「でもメソッドの数が多いときはextend self
でまとめてやりたくなるかも」
「記事によると、module_function
の場合は、モジュールをオープンクラス的に再度開いて同名のメソッドを再定義しても、module_function
を再度呼ぶまでは、module_function
の対象は最初に定義したメソッドのままで、再定義したメソッドに自動的に差し変わらないんだそうです↓」「お〜、そうなのか!」
# 同記事より
module ModuleFunction
def who_am_i
"ModuleFunction"
end
module_function :who_am_i
end
ModuleFunction.who_am_i # => "ModuleFunction"
module ModuleFunction
def who_am_i
"overriden ModuleFunction"
end
end
ModuleFunction.who_am_i # => "ModuleFunction"
module ModuleFunction
module_function :who_am_i
end
ModuleFunction.who_am_i # => "overriden ModuleFunction"
「逆にextend self
の場合は、同名のメソッドを再定義した時点で自動的に新しいメソッドの方が呼び出されるようになる↓」
# 同記事より
module ModuleFunction
extend self
def who_am_i
"ModuleFunction"
end
end
ModuleFunction.who_am_i # => "ModuleFunction"
module ModuleFunction
def who_am_i
"overridden ModuleFunction"
end
end
ModuleFunction.who_am_i # => "overridden ModuleFunction"
「記事の最後でextend self
とmodule_function
のメリットを比較していますね↓」「"module_function
の方が読みやすい"、おっしゃるとおり」「公開されるメソッドが明示されますからね」
extend self
module_function
「この挙動の違いを業務コードで使い分けることがあるかしら」「たぶんない😆」「記事の最後に、"module_function
はRuby標準ライブラリでものすごく使われている"と書かれていますね」「いわゆるユーティリティ関数用のモジュールで多用されるのはわかる」「数学関数みたいな、インスタンス化しないで使う関数のモジュールですね」「数学関数をnew
することはまずないでしょうね」
「学びのある記事👍」「Rubyにはまだまだ知らないことがあった」
そういえばずっと前に記事を書いて以来module_function
のことをすっかり忘れてました↓
🔗 その他Ruby
大枠の草案を @jishiha さんに作ってもらえたおかげで使い方がサッと掴めたので色々遊んでみています 🛠💨✨ https://t.co/BvAOCsBkSZ
— 安川要平/Yohei Yasukawa (@yasulab) November 29, 2022
つっつきボイス:「ツイートのリンクをクリックするとリポジトリを開けます」「お〜、このマップですね↓」「うちの近所にCoderDojoの教室あるかな」(しばしマップをつつく)
参考: 地図から探す (DojoMap) - CoderDojo Japan
🔗DB
🔗 AWS RDSがBlue/Greenデプロイに対応
MHA自体はさほど新しいコンセプトではないとは思います。マネージドサービスになってるのが利点ではある。
— 7594591200220899443 (@shyouhei) November 29, 2022
つっつきボイス:「@shyouheiさんのツイートにもあるように、このコンセプト自体は昔からあるものですね」「なるほど」「これを自力でやると大変なので、マネージドなのはたしかにありがたい: ただ、今あるものに足すというよりは最初から構成しておく必要があるようですけど」
参考: より安全、簡単、迅速な更新のための Amazon RDS ブルー/グリーンデプロイを発表
参考: MySQL を MHA + HAProxy で冗長化してみよう - インフラエンジニアway - Powered by HEARTBEATS
MHA for MySQL: Master High Availability Manager and tools for MySQL
Google Code Archive - Long-term storage for Google Code Project Hosting.より
「こういう仕組みは大きめのデプロイをやるときに欲しくなりますね: productionとstagingを完全同期しておいて、破壊的変更をstagingにリリースした上でproduction <-> stagingの役割を切り替えるというもので、サーバー2つ分の費用がかかる代わりに問題が起きたらすぐ元に戻せるのが強み」
「これなしでエイヤでデプロイしてミスしたら目も当てられないし、数か月前から計画を立てる必要があって作業者や期間のコストもかさむ」「作業のストレスも半端ないですよね」
「こういうサービスが10年前に欲しかった...」「呼び方はいろいろあれど、似たようなことは昔から行われていましたね: まあ10年前にそういうサービスがあってもすぐには信用できなかったでしょうけど」「それわかります」
「実はこのBlue/Greenデプロイという用語を知りませんでした😅」「私が昔作ったスライドがありますのでどぞ↓」「どもです!」
🔗 設計・セキュリティ
🔗 マトリョーシカ人形のようなメソッド設計を避ける
ブログ書きました。プログラミング初心者の方がやりがちなミスとその解決策について書いてます。 #fjordbootcamp
マトリョーシカ人形のようなメソッド設計を避ける - give IT a try https://t.co/4H63VHBBwF
— Junichi Ito (伊藤淳一) (@jnchito) November 27, 2022
つっつきボイス:「jnchitoさんの記事です」「メソッドチェインを追いかけないと何をやっているのかわかりにくいコード、あるある」「それをマトリョーシカ人形と呼んでるんですね、なるほどわかりみです」
「RuboCopのMethodLengthを回避しようとして、メソッドを細切れにしてチェインする書き方をする人がときどきいるんですよ」「RuboCopがメソッドの行数を増やすなって怒るのもわかるんですけど、あれを守るのはつらい」「分割すること自体はいいんですけど、再利用しないものまで超細かく分割されるとむしろ読みづらい」「ズキッ!耳痛い...」
参考: MethodLength
-- Metrics :: RuboCop Docs
後編は以上です。
バックナンバー(2022年度第4四半期)
- 20221130後編 Ruby 3.2のParser目玉機能ほか
- 20221129前編 Hanami 2.0リリース、Railsに関わる技術の体系化を目指した本ほか
- 20221122 The Rails Foundation発足、Ruby 3.2.0 Preview 3リリース、Ruby演算子クイズほか
- 20221116後編 Rubyを使っている企業の時価総額リスト、irbのshow_source、GitHub Codespacesほか
- 20221115前編 RailsチュートリアルがRails 7対応版をリリース、ViewComponentで使えるLookbookほか
- 20221102後編 書籍『Programming Ruby 3.2 (5th Edition)』、ReDoSチェックサイトほか
- 20221101前編 Packwerkの詳しい解説書『Gradual Modularization for Ruby and Rails』ほか
- 20221026後編 Ruby 3.2のData.define、RubyPrize 2022最終ノミネート、Puma-dev gemほか
- 20221025前編 rodauth-rails gem作者の解説記事、turbo-railsの有料チュートリアルほか
- 20221019後編 Ruby技術者認定試験再受験無料キャンペーン、Starlink日本で販売開始ほか
- 20221018前編 Rails向けLanguage Server “refreshing”開発中、JetBrains Fleetほか
- 20221012後編 RailsとPostgreSQLで列挙型を作成する6つの方法、Ubuntu Proほか
- 20221011前編 Turbo 7.2.0リリース、GitLabのDevSecOpsサーベイ結果ほか
- 20221004後編 ヒアドキュメント拡張の提案、『組織に自動テストを根付かせる戦略』ほか
- 20221003前編 Kaigi on Rails 2022のタイムテーブル発表、書籍『Practicing Rails』ほか
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp SlackやRedditなど)です。
週刊Railsウォッチについて
TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)