- Ruby / Rails関連
週刊Railsウォッチ: The Rails Foundation発足、Ruby 3.2.0 Preview 3リリース、Ruby演算子クイズほか(20221122)
こんにちは、hachi8833です。
🔗Rails: 先週の改修(Rails公式ニュースより)
🔗 Enumerable#many?
を修正
再現手順
追加のブロックパラメータを渡す別の関数(each_with_index
など)にmany?
をチェインし、ブロックを渡して呼び出す。このブロックは要素だけを受け取り、追加のブロックパラメータがforwardされない。これはすべてのブロックパラメータをforwardするany?
と振る舞いが異なる。# frozen_string_literal: true require "bundler/inline" gemfile(true) do source "https://rubygems.org" git_source(:github) { |repo| "https://github.com/#{repo}.git" } # Activate the gem you are reporting the issue against. gem "activesupport", "~> 6.1.0" end require "active_support" require "active_support/core_ext/object/blank" require "active_support/core_ext/enumerable" require "minitest/autorun" class BugTest < Minitest::Test def test_stuff [1, 2, 3].each_with_index.many? do |element, index| assert index.present? assert index == element - 1 end end end
期待される動作
呼び出し側のブロックがすべてのブロックパラメータを受け取る。
実際の動作
呼び出し側のブロックが要素だけを受け取る。
システム構成
Rails: 6.1.6.1
Ruby: 2.7.5p203
#46445より
つっつきボイス:「Active SupportのEnumerable
拡張にmany?
というメソッドがあるって知らなかった」「要素が2個以上ならtrueを返すんでしょうね」「このプルリクでは、many?
メソッドをチェインしたときにブロックがうまく転送されていなかったのが修正されたようですね」
- Rails API
many?
--Enumerable
🔗 ActiveRecord::PendingMigrationError
で未実行のマイグレーションファイル名をフルパスで出力するようになった
filename
はパスを提供するがbasename
は提供しない。マルチDBアプリではマイグレーションがさまざまなディレクトリに保存されるので、ファイル名をフルパスで表示する方がよい。
同PRより
つっつきボイス:「マイグレーションを忘れたときに出るエラーですね」「basename
をfilename
に変更することで、どのパスにあるマイグレーションファイルが未実行かが表示されるようになったのはいい👍」「developmentモードでしか表示されないメッセージだからフルパス表示でも問題ないでしょうね」
# activerecord/lib/active_record/migration.rb#L162
pending_migrations.each do |pending_migration|
- message += "#{pending_migration.basename}\n"
+ message += "#{pending_migration.filename}\n"
end
🔗 ダークモードのエラーハイライト表示を改善
動機/背景
#45818のフォローアップ。今はダークモードで以下のように表示される。濃い黄色で見づらくない色合いを試行錯誤した結果、以下にしてみた。
この色合いについて遠慮なくサジェスチョン求む。
同PRより
つっつきボイス:「何を修正したかったかがひと目でわかる」「ダークモードで白い文字の背景が明るいとたしかに読みにくい」「ダークモードって作業がいろいろ増えがちですよね」
🔗 MissingExactTemplate
エラーページにコントローラ名とアクション名も表示
動機/背景
このプルリクは、コントローラ名とアクション名をエラーページにパススルーしてはどうかという@jhawthornの以下の提案↓を実装したもの。@olivierlacanの素晴らしいプルリク#46342にエラーページの改善を加える形で構築する。
同PRより
これはとてもいい!ところでそれとは別に、期待されるコントローラとアクションもパススルーすることが可能なら、実際に作成したいメッセージを暗黙のレンダリングでこのメッセージに含められるのでは?
#46342コメント(by jhawthorn)より
つっつきボイス:「エラーページにクラス名とアクション名も表示するようになったんですね」「これもdevelopmentモードのみなので、情報は多い方がいい👍」
# actionpack/lib/action_controller/metal/implicit_render.rb#L43
elsif interactive_browser_request?
message = "#{self.class.name}\##{action_name} is missing a template for request formats: #{request.formats.map(&:to_s).join(',')}"
- raise ActionController::MissingExactTemplate, message
+ raise ActionController::MissingExactTemplate.new(message, self.class, action_name)
else
🔗Rails
🔗 The Rails Doctrineの日本語訳が進行中
つっつきボイス:「日本Rubyの会代表の@takahashimさんが "The Rails Doctrine" の日本語化を進めているのを最近になって知りました」「この翻訳自体は昨年3月に投稿されていたんですね」「元の英語版は割と前からあったはずで以前読んだ覚えもありますが、この翻訳が公式へのマージを目指しているのはよさそう👍: そのうち久しぶりに読み返してみようかな」
後でarchive.orgで見るとThe Rails Doctrineは2016年からありました。
「この気持わかる↓」「exitしたいことがわかっているならexitして欲しいですよね」「Pythonは関数呼び出しの()
を省略できないから、()
なしのexit
を実行できたら逆にびっくりするかもしれないけど、Rubyは省略できるので、()
なしのexit
やquit
をメソッドとして問題なく実行できますよね」「こういう細かい部分の気遣いがRubyらしい点」
# The Rails Doctrineより
$ irb
irb(main):001:0> exit
$ irb
irb(main):001:0> quit
$ python
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
「ところで、このvalidates_presence_of :name
という書き方↓は割と古いかも(今も一応使えるけど)」「今はpresence:
をオプションで渡すんでしたっけ」「そうそう、validates :name, presence: true
みたいに書くのが主流ですね」
# The Rails Doctrineより
class Project < ApplicationRecord
belongs_to :account
has_many :participants, class_name: 'Person'
validates_presence_of :name
end
参考: validates
-- ActiveModel::Validations::ClassMethods
「ところで、以前に比べてRailsに対する批判を見かけることが減った気がしますね」「それはあるかも」「新規プロジェクトを何でもかんでもRailsで作り始めることが以前より減ったからかもしれませんね」
後ほど私も日本語訳にいくつか編集リクエストを投げてマージいただきました🙏。
🔗 GitHub元CTOのツイート
First, these are thoughts, not rules. Anyone that has built a large distributed system knows they don't really work that way and have to adapt with it
Second, stage will be important. If you are reading this at a 5-50 person company...just stick with a monolith. Trust me
— Jason Warner (@jasoncwarner) November 14, 2022
つっつきボイス:「以下のScrapbox記事で詳しくまとめられていますが、GitHub元CTOのJason Warnerによるマイクロサービスについての上の発言が議論になっていたそうです」「最後まで読まずに反応する人はどうしても一定数いますよね」「定番の話がいろいろまとまってていい👍」
参考: Jason Warnerとマイクロサービス - 西尾泰和のScrapbox
「まとめには、"スピードとリスク"のようなThe Rails Doctrineに通じる話もいくつかありますね」「マイクロサービスは、ドメイン境界の設計やサービスごとの役割の切り分けを行う人がものすごく有能でないと、一般には難しい面があると思います」「マイクロサービス化が進むほどRPCの頻度がものすごく高まったりログの量も増えたりしますよね」「そういえばGitHubも部分的にマイクロサービスを導入したという話を見かけた覚えがあります」「GitHubの規模なら避けられないでしょうね」
参考: GitHubのモノリスからマイクロサービスへのジャーニー
「まとめにある"できるだけ長くモノリスであること"というのは本当にそのとおりだと思います: マネタイズの見極めがつくとかそういうときが来るまでは、なるべくモノリスのままにしておきたい」「そうですね」「もちろんアプリの中には切り離しやすい部分もあれば切り離しにくい部分もあるので、切り離しやすい部分をしっかり見極められるなら必要に応じてマイクロサービス化を検討するのはありだと思います」
「"モノリスから脱却する場合小さなサービスではなく大きなアプリに分割する"も前から言われていて、これも同感」「そうそう、マイクロサービスは機能で分割するのではなく業務ドメインで分割しようみたいな話ですね」「そうしないと何をするにも大量のAPI呼び出しが発生したりしがち」
「これも昔から言われていますね↓: たいていのアプリはこうした伝統的な3レイヤアーキテクチャでまかなえると思います」
世界中の企業の90%は、プライマリDBクラスタとDBバックアップ、キャッシュ、プロキシで動作するモノリスで済ますことができるだろう。
Jason Warnerとマイクロサービス - 西尾泰和のScrapboxより
「ちなみに上のツイートは以下の発表を視聴していて知りました↓」「お〜、こんなミートアップが開催されていたんですね」
参考: 【iCARE Dev Meetup #36】Rejected CFP 供養会 2022 - connpass
🔗 The Rails Foundationが発足(Rails公式ニュースより)
The Rails Foundation kicks off with one million dollars from @cookpad, @doximity, @fleetio, @github, @intercom, @procoretech, @Shopify, and @37signals to improve the documentation, education, marketing, and events in our ecosystem 🎉 https://t.co/25tKsWmVIu
— Ruby on Rails (@rails) November 14, 2022
つっつきボイス:「The Rails Foundationという公式な団体が、1企業がすべてを采配しない形で立ち上げられたのはいいことだと思います👍」
In alphabetical order, the eight founding core members of The Rails Foundation are: Cookpad, Doximity, Fleetio, GitHub, Intercom, Procore, Shopify, and 37signals.
Ruby on Rails — The Rails Foundation kicks off with one million dollarsより
「ところで本筋と関係ないんですが、創立メンバーリスト↑がalphabetical orderと書かれているのに37signalsが最後尾にあるのがちょっと面白い」「アルファベット順なら数字が最初に来そうですよね」「推測ですが、英語圏の慣習では37みたいなアラビア数字よりもthirty-sevenのようにスペルアウトした形が正式という意識が強いからじゃないかなと思いました」「へ〜」「英語圏では特に文章がアラビア数字で始まることを嫌う傾向があるんですが、おそらく箇条書きと紛らわしいからだろうと思います」
参考: 【ビジネス英語】数の表記は数字?アルファベット?使い分けのルールを知ろう | みんなの仕事Lab-シゴ・ラボ-
🔗 その他Rails
- 元記事: Zeitwerk を単体で使う方法
つっつきボイス:「小ネタ記事です」「たしか従来のオートローダーがRailsに密結合しすぎていたからというのZeitwerkが開発された動機だったと思うので、単体で使えてもおかしくないでしょうね: こういうのをやってみるのは勉強にいいですね👍」
参考: Classic から Zeitwerk への移行 - Railsガイド
「Zeitwerkがオプショナルな形でRuby本体に入る可能性はあるでしょうか?」「Rubyには前からModule#autoload
がありますし↓、オートローダーのパフォーマンスが問題になるほど大規模なアプリ以外でZeitwerkが欲しくなることは少ないと思うので、Ruby本体に入る可能性はあまりないんじゃないかな」「なるほど」
参考: Module#autoload
(Ruby 3.1 リファレンスマニュアル)
🔗 Ruby
🔗 Ruby 3.2.0 Preview 3リリース(Ruby公式ニュースより)
Link: Ruby 3.2.0 Preview 3 リリース
https://t.co/LmaA67lbCE— Yukihiro Matz (@yukihiro_matz) November 12, 2022
つっつきボイス:「Preview 3がリリースされる季節になったか〜」「3.2.0最終リリースももうじきですね」
「koicさんの以下の記事も貼りました↓」「Bisonのバージョンも気をつけないといけないのね」
参考: Ruby 3.2 (dev) のビルドに Bison 3 以上が必要になる - koicの日記
「ちなみに自分は3.2.0-devのビルドが未だに成功していません🥲」「マジですか」「M1環境なのと、どこかで設定をしくじっているような気もするんですが、BisonをアップデートしたりYJITをオフにしたりいろいろやってもビルドできず...」
その後オプションをいろいろ変えて、最新の3.2.0-dev(v20221121)と以下のオプションでやっとビルドに成功しました。まだM1で--enable-yjit=dev
はできないようです。
$ export RUBY_CONFIGURE_OPTS="--disable-yjit --with-opt-dir="$(brew --prefix openssl):$(brew --prefix readline):$(brew --prefix libyaml)" --disable-install-doc --disable-install-rdoc"
$ rbenv install 3.2.0-dev
To follow progress, use 'tail -f /var/folders/6_/412tm5md0svdq66fxwwgn0tw0000gn/T/ruby-build.20221122140346.89512.log' or pass --verbose
Downloading openssl-3.0.7.tar.gz...
-> https://dqw8nmjcqpjn7.cloudfront.net/83049d042a260e696f62406ac5c08bf706fd84383f945cf21bd61e9ed95c396e
Installing openssl-3.0.7...
Installed openssl-3.0.7 to /Users/hachi8833/.anyenv/envs/rbenv/versions/3.2.0-dev
Cloning https://github.com/ruby/ruby.git...
Installing ruby-master...
ruby-build: using readline from homebrew
ruby-build: using gmp from homebrew
Installed ruby-master to /Users/hachi8833/.anyenv/envs/rbenv/versions/3.2.0-dev
$ ruby -v
ruby 3.2.0dev (2022-11-22T02:32:28Z master 36f297e621) [arm64-darwin22]
🔗 Rubyの演算子クイズ(Ruby Weeklyより)
つっつきボイス:「Rubyのクイズサイトです」「お、面白そう〜」「全部で12問で制限時間があるのね」(しばし全員でつっつく)
「4択とはいえ、制限時間内に答えるの結構むずい」「and
とor
や&&
と||
の優先順位の違いとか」「<<
ってビットシフトだったか」「irbで動かせば一発だけど、やったら負けなんでしょうね...」「普段使わないような書き方が多いですよね」「終わったら解説が表示されるんですね」「知らない挙動がいくつもあった」「Ruby技術者認定試験でこんなの出たらつらそう」「Ruby技術者認定試験の問題にはこんな感じのが出ることもありますね」「これは楽しい👍」
参考: Ruby技術者認定試験
🔗 Rubyのメモリ使用量を減らす方法(Ruby Weeklyより)
つっつきボイス:「一口メモ的な記事です」「MALLOC_ARENA_MAX=2
はどこかで見たと思ったら以下のNate Berkopecさんの記事にもありました↓」「MALLOC_ARENA_MAX
ということはglibc方面の話ですね」
参考: The GNU C Library -- glibc
その他Ruby
#rubyworld で、Matzがお話してくれた内容を、自身の復習も兼ねてまとめてみました!よかったらご覧ください🙌 pic.twitter.com/4Qi5QlNCxY
— あちゃ (@achamixx) November 15, 2022
つっつきボイス:「RubyWorld Conference 2022のMatzのキーノートスピーチのまとめですね(ウォッチ20221116)」
🔗DB
🔗 HEYでページネーションを高速化(Ruby Weeklyより)
つっつきボイス:「HEY.comを手掛けている37signalsの記事です」「MySQLのEXPLAINで結果を確かめつつ、複合インデックスを作ってからFORCE INDEXするという定番の手法ですね: MySQLはデフォルトでインデックスが統計情報に応じて動的に選択されてしまうので、明示的に使って欲しい特定のインデックスがある場合にはFORCE INDEXを使わないと想定通りに動かないことがよくあります」
参考: HEY - Email at its best, new from 37signals.
-- 同記事より
mysql> EXPLAIN
-> SELECT `topics`.*
-> FROM `topics` FORCE INDEX(index_topics_on_account_id_and_id_and_status_and_dates)
-> INNER JOIN `accesses` ON `accesses`.`topic_id` = `topics`.`id`
-> WHERE `accesses`.`contact_id` IN (
-> SELECT `contacts`.`id`
-> FROM `contacts`
-> INNER JOIN `users` ON `contacts`.`contactable_id` = `users`.`id`
-> WHERE `users`.`identity_id` = 280304
-> AND `contacts`.`contactable_type` = 'User'
-> )
-> AND `topics`.`status` = 5
-> AND `accesses`.`account_id` = `topics`.`account_id`
-> ORDER BY `topics`.`active_at` DESC, `topics`.`id` DESC
-> LIMIT 15;
参考: MySQL :: MySQL 8.0 リファレンスマニュアル :: 8.9.4 インデックスヒント -- FORCE INDEX
「ところで37signalsとBasecampってどういう関係でしたっけ?」「最近社名が変わったみたいな話を見かけた気がするけどどうだったかな🤔」
後で調べると、2022/05/03にBasecampが社名を37signalsに改名したというアナウンスが出ていたことを今になって知りました↓。37signalsという名前はBasecampの初期の社名だったそうです。
Wikipedia英語版によると「(1999創立)37signals -> (2014)Basecamp -> (2022)37signals」のように社名が変遷していたんですね。なおbasecamp.comのサービス名はこれまでどおりBasecampです。
参考: 37signals: Hello again
参考: 37signals - Wikipedia
参考: Basecamp: Project management software, online collaboration
🔗 設計・セキュリティ
🔗 素のRailsは十分に豊かである(Ruby Weeklyより)
既に翻訳許可をいただいたので、近々公開いたします。
つっつきボイス:「YassLabの安川さんから教えていただいた記事で、これも37signalsです」「Vanilla Railsって素のRailsですか」
バニラ(英語:Vanilla)とは、コンピュータソフトウェア、まれにコンピュータのハードウェアまたはアルゴリズムなどで、改変・改修・カスタマイズなどが一切行われていない、提供された状態のまま(原型を留めたままの状態)を指す。
バニラという表現は、業界でもデ・ファクト・スタンダードとして標準的に企業や個人で広く利用されている。語源は、アイスクリームの標準的な風味であるバニラ味からきている。エリック・レイモンドのジャーゴンファイルによると、バニラは "default" (デフォルト)よりは "ordinary" (普通の・平凡な)の意に近いとしている。
バニラ (ソフトウェア) - Wikipediaより
「境界を仕切るようなgemに頼らずに、concernsやPORO(Plain Old Ruby Object)を使いこなす形でやっていくのをVanilla Railsと呼んでいるようですね: クリーンアーキテクチャのような大掛かりなものを使わなくてもここまでやれるという感じ」「なるほど」「安易にgemを入れたりせずに解決するやり方はいいと思います👍」
「記事の最後に"37signalsに入社してみてコードの品質がめちゃくちゃ高いことに驚いた"、"DDD(ドメイン駆動設計)を使ってないのにDDDを見事に体現している"みたいなことが書かれてますね」「HeyやBasecampのように情報だけを扱うタイプの自社開発アプリは、素のRailsで比較的きれいに設計しやすいという側面はあるでしょうね」「それもそうですね」
「対照的に、たとえばShopifyのようなサービスはものすごく複雑な現実を相手にしているので、そういうところではPackwerk(ウォッチ20220920)のような境界を仕切るgemが欲しくなるだろうということも想像できます」「なるほど」「国ごとの通貨や法律の違いや外部連携や頻繁な仕様変更といった複雑な現実を相手にするようになると、きれいに抽象化できないとか例外的な扱いをせざるを得なくなることが発生しやすいんですよ」「そうなんですよね...」「そういう複雑な現実をマイクロサービスで切り離そうとしてもあまりうまくいく気がしない」「結局敵は現実世界か...」
🔗JavaScript
🔗 Symfony UXでHotwire技術が導入されている
Hello https://t.co/5T2MbD5GgN & 4 New UX Components https://t.co/EK1rPRTS7I #symfony
— Symfony (@symfony) June 21, 2022
つっつきボイス:「今日のWebチーム内発表で触れられていたヤツです」「SymfonyはPHPのWebフレームワークで自分も以前使ったことがありますが、このSymfony UXではHotwireのStimulusとTurboを使っている」「curated by Symfonyと書かれていますね」「名前空間もsymfonyになっているので公式のものですね」「HotwireはRailsがなくても使えるんですよね」「結局みんなだいたい同じようなところで悩んだり詰まったりするので、RailsやSymfonyなどで欲しいものが似通ってくるというのはあるでしょうね」
今週は以上です。
バックナンバー(2022年度第4四半期)
週刊Railsウォッチ: Rubyを使っている企業の時価総額リスト、irbのshow_source、GitHub Codespacesほか(20221116後編)
- 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ウォッチタグ)