はじめに
完全に自分の備忘録です。
Ruby/Rails環境で開発をするときにとても有用な記事を日本語訳して、解説してくれているのでRubyist、Railsエンジニアで知らない人はにわか(暴論)。
読んだ記事はここで管理することで、あれ?なんか読んだことあるな、まぁいっか(読もう)みたいな時間の無駄をなくしたい。
はい、本当は何度も読むこともいいことなのですが、こんだけ読んだぜ!って自己満足するためです。
悪しからず。
週刊Railsウォッチ既読一覧
2017年以前
メソッドの定義元を調べる方法。
Class.method(:method_name).owner
ベストプラクティスのまとめ。
定期的に読み返したい。
ガーベジコレクタとかの話。
雑に読んだ。ほぼわからない。
2つ読んだ。
一つ目は"Rails: ActionMailer::Baseからのrequire "active_support"の脱落を修正"。
この記事を参照することになったきっかけなのだが、
require "active_support"をしないと読み込めない拡張機能があるらしい。
require "active_support/time"はrequire "active_support"しなくても読めた。
Railsは基本的にActive Supportのすべての拡張機能を読み込む。
— Taku Kunita (@takkuso1105) August 2, 2022
Rubyのみの場合は任意の拡張機能をrequireしないと使えない。
ちなみに require 'active_support/time' だけでDateTimeもInteger#hourも使えた。
core_ext拡張は先に require 'active_support' をしないとロードできない。
なぜ。 pic.twitter.com/AlRkmYZz0e
なぞだ。
2つ目はシャドウイングの記事。
2018年
BPF(Berkeley Packet Filter)の拡張を使って、mallocをprofilingする話。
難しい。
superキーワードの4つの側面。
Rubyではパーレンなしでも継承チェーンをさかのぼってスーパークラスのメソッドの引数を勝手に解釈してくれる。
全然関係ないけど、superってJavaっぽい。
Rubyとの違いは、Javaはコンストラクタは自動で読まれるのでsuper()(パーレンつき)は要らなかったはず。
Enumerableクラスにいいメソッドがたくさんあるよって話。
injectメソッドの使い方が微妙に変というところに納得しました。
原文からしてそうだけど、#injectの例は微妙に適切じゃないと思う。公式ドキュメントで挙がってる「total + number」の方が良い。ブロックの返り値が次のループのtotalになるので。
これも合わせて読んだ:
2019年
Railsのエコシステムの話。
2009年の記事の紹介で、Railsコミュニティ活発にしようぜ!という話。(ざっくりすぎ)
あとStrong_parametersでバリデーションする記事について、
フィルターとバリデーションって責務が違うのでそれぞれコントローラー、モデルで
処理を分けるのがRailWayなのかなと思ったのだが、
どうやらAPIモードで利用するときはコントローラーでもバリデーションするような
ユースケースがあるらしい。
たぶんだけど、スキーマ駆動開発とか、APIドキュメントにバリデーションの記載を
含めたくなるようなときに必要なんじゃないかなぁと。
その場合、apipie-railsというgemが便利らしい。
N+1問題をBulletで発見できないパターン。
実際にハンズオンでやってみた。
集計関数を使ったN+1問題にもRuby3系/Rails7系でやったらしっかり警告してくれた。
今ではもう起きないかも?
その他、rack-mini-profilerをインストールしてクエリ実行を含めた計測を実施した。
親子だけ、データが少なめだったのであまり差が出なかったため、時間あればもう少し大きなデータ、遠い関係でやってみたい。
web | Post Load (1.1ms) SELECT `posts`.* FROM `posts` /*application:Myapp,controller:posts,action:index*/ web | ↳ app/views/posts/index.html.erb:6 web | Comment Load (0.9ms) SELECT `comments`.* FROM `comments` WHERE `comments`.`post_id` = 1 /*application:Myapp,controller:posts,action:index*/ web | ↳ app/views/posts/index.html.erb:12:in `map' web | Comment Load (0.9ms) SELECT `comments`.* FROM `comments` WHERE `comments`.`post_id` = 2 /*application:Myapp,controller:posts,action:index*/ web | ↳ app/views/posts/index.html.erb:12:in `map' web | Comment Load (2.1ms) SELECT `comments`.* FROM `comments` WHERE `comments`.`post_id` = 4 /*application:Myapp,controller:posts,action:index*/
web | SQL (1.2ms) SELECT `posts`.`id` AS t0_r0, `posts`.`name` AS t0_r1, `posts`.`created_at` AS t0_r2, `posts`.`updated_at` AS t0_r3, `comments`.`id` AS t1_r0, `comments`.`name` AS t1_r1, `comments`.`post_id` AS t1_r2, `comments`.`positive_count` AS t1_r3, `comments`.`negative_count` AS t1_r4, `comments`.`created_at` AS t1_r5, `comments`.`updated_at` AS t1_r6 FROM `posts` LEFT OUTER JOIN `comments` ON `comments`.`post_id` = `posts`.`id` /*application:Myapp,controller:posts,action:index*/
web | Post Load (1.0ms) SELECT `posts`.* FROM `posts` /*application:Myapp,controller:posts,action:index*/ web | ↳ app/views/posts/index.html.erb:6 web | Comment Load (1.3ms) SELECT `comments`.* FROM `comments` WHERE `comments`.`post_id` IN (1, 2, 4) /*application:Myapp,controller:posts,action:index*/
web | Post Load (1.1ms) SELECT `posts`.* FROM `posts` /*application:Myapp,controller:posts,action:index*/ web | ↳ app/views/posts/index.html.erb:6 web | Comment Load (1.3ms) SELECT `comments`.* FROM `comments` WHERE `comments`.`post_id` IN (1, 2, 4) /*application:Myapp,controller:posts,action:index*/
2020年
2021年
もともとは2013年の記事だけど、今の環境でも通用するように再編集したっぽい。
#Form Objectに切り出す
まで。
週刊Railsウォッチ以外の記事。
Rustはいいぞという話。
人間の脳は差異によって認知が上がるので(謎理論)、
言語ごとの違いで深い洞察を得たいと思っている。
RubyとRustは最初の2文字が同じだけでそれ以外は全然違う(?)。
余裕が出てきたらRustも書けるようになりたい。
2022年
curl-to-ruby(curlコマンドをRubyコードに変換するサイト)とかおもしろそう。
簡単に触ってみる限りだとcurlの細かいオプションに対応していないっぽい???
Devツールも便利な使い方があるのは知っているんだけど、ほとんど基礎的なことしかできない。。。
学びなおしたいな。
SPA vs. MPAの記事は削除されていて魚拓もなかったけど、はてぶコメント読むとPros&Cons議論がされてておもしろかった。
個人的にはWebで速度気にしたことないから(数秒くらい全然待ってもいい勢)バックエンドもExpressとかNode.jsにして全部TS!とか言うあたおかスーパープログラマの世界線の話かな。
子プロセスをコピーオンライトによってプロセスをfolkするときも従来ほど遅くならない??
全体的にだいぶ難しかった。
また様子見て読み返す。
合わせて読んだ:
fork(2) で子プロセスを生成しなくてすむ。fork(2) はかなり重いシステムコールである。fork(2) が重いので、vfork(2) が作られたくらい重い。ただ、現代の UNIX では copy-on-write の効果により、以前ほど fork(2) が重いわけではない。
シェルからlsコマンドを実行すると、シェルは以下のことを行う。
システムコール fork() を呼び、子プロセスを生成する。
子プロセスは ls を exec() する。
親プロセスであるシェルは、ls の実行が完了するのを待つ (wait する)。
このように,あるコマンド(またはプログラムやシェル)から,別のコマンドを呼び出すということは,プロセスの親子関係を生み出すという行為になる。
ちなみに,「プロセス間の親子関係を断ち切る」のがデーモン。
(例えば Apache Webサーバーのhttpデーモンなど)
デーモンを呼び出すと,自分の子プロセスとはならず,initの子プロセスになる。(後述する。)ただし、子プロセスが設定した環境変数は親プロセスには影響を与えませんし、全く無関係のプロセス(親子の関係にないプロセス)にも反映されません。
常に設定しておきたい環境変数は、.bash_profile などの中で、ログイン時に設定するといいでしょう。
ファンイン、ファンアウトという言葉を初めて知った。
「そういえばAND回路は2入力1出力だから、ファンインが2でファンアウトが1、みたいに言いますね」
合わせて読んだ:
change_column_null
なんてもう忘れた。
null制約のためのマイグレーション用メソッドなので、第3引数をtrueにしたら制約され、falseだとnull制約がなくなる。逆に覚えそうで怖い。
Vite.jsなるものが気になる。
GitHub Copilotのライセンス違反問題がとても気になる。
"Active Recordの「Leaky Abstraction」を削減する"
Controllerでよく使うクエリはModelのクラスメソッドにしようという話。
いろいろ語弊があるかもしれないけど。
さいごに
Thanks to TechRacho. Your articles are all very practical!!