Ruby Weekly #361: 日本語サマリー
職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。
Highlights
dependabot(依存 gem チェッカー as a Service)のバグ改修で Bundler を 2 倍速くした話。
バグは Bundler の依存関係解決ロジック(Molinillo gem に抽出されてる)にあった。バックトラッキングアルゴリズムが複雑すぎて、リファクターすることに。そこで閃いて、グルーピングで 10 倍高速化。
次バグ改修したが、今度激重くなった。フィルタリングしてみたら今のスピードになった。
YAML から巨大 Hash を読み込む Rails アプリのメモリが気になり、Ruby メモリ計測方法調べてみた話。
String#bytesize
で文字列単位計測- memory_profiler gem でブロック単位(
Total retained
値) - derailed_benchmarks gem の
derailed exec perf:mem_over_time
で多数リクエストを投げてメモリ計測
結論:3 の数値が横ばいになっていくから Hash 巨大化してもメモリへの影響はさほどない。
Rails の CSRF 対策の内部実装をコードリーディングした話。
Enumeration 上級者編
- Enumeration とは
Enumerator
の最低条件- Lazy vs Not Lazy
- 上級者活用例
- グループ分け
- フォールディング
- Struct
「Rails 終わったなんてデタラメ」ブラジル RubyConf 元オーガナイザー Fabio Akita 氏。 Rails 経歴を振り返りながら、先々週の Coding Dojo ブートキャンプ騒ぎに反論。
2003 年。SNS 元年。
2004 年。Gmail 誕生。FB 急上昇。常識を覆す Rails がブラジルの無名カンファレンスで登場。
2006 年。Twitter、Groupon、Engine Yard 登場。AWS S3・EC2 リリース。インディーズでもスケーリングが可能に。
2007 年。Heroku 誕生。Git リリース。iPhone 発売。
2008 年。GitHub 誕生。DevOps 元年。Zed Shaw が Ruby から引退した騒ぎ。Rails + Merb 結合。
2009 年。Apple ネイティヴ SDK リリース。NoSQL 元年。Twitter が Scala に移行。
2010 年。Apple が Flash に対して宣戦布告。Rails 全盛期。
2011 年。Ruby、Objective-C が主流となった。
2012 年以降。Rails 屋さんから生まれた、なんでも作り直したがる不満げなエンジニアの時代。Go、Elixir、Scala などニッチ言語に流出。
結論:Rails 終わったなんて大げさ。常識を覆さなくなったのは、Rails が常識になったから。
- キー命名統一しろ
- ダブらせるな
- 文字列前後に
"
付けろ(YAML パース失敗 → Rails ブート失敗の原因。超デバッグし辛い) - ローカライズ外注先とのワークフロー決めろ
- 該当文章が見つからなかった場合は機械翻訳をフォールバックに(コードあり)
- YAML ファイル名とファイル内ロケールが一致しているかテスト書け
Tutorial
DynamoDB で has_many
アソシエーションをモデリングした話。1 テーブルでのモデリングと 2 テーブルでのモデリングを比較した。
社内 gem を Gemfury(有料)でホスティングしてた Showoff 社が、gemstash でセルフホスティングにした手順。
- EC2 インスタンス作成・設定
- gemstash 用 Rails アプリ作成
- Capistrano 設定
- gemstash 設定(認証有無)
- デプロイ
gemstash
コマンドでプッシュ用キー作成- 社内 gem を gemstash にプッシュ
gemstash
コマンドでフェッチ用キー作成、Gemfile に埋め込む
テストが不安定になる原因
N+1 クエリ撲滅方法
includes
- bullet gem
おまけ
- Semaphore CI では bullet.log もジョブ毎に表示できる!という執筆者のステマ
Bullet.raise = true
で CI ビルドをレッドにしよう- 既存 N+1 が多すぎる場合は、ホワイトリストに追加して、新規クエリのみ CI 対象にしよう
RSpec の --profile
オプションで重いテスト特定して潰していこう。
Create a State Machine with AASM, Sequel, SQLite, Rake, and RSpec
AASM gem + Sequel で state machine 実装、RSpec でテスト。
Shoryuken gem + Amazon SQS の FIFO キューでバックグラウンドジョブ処理。
FIFO キューの特徴
- ジョブのグループ分け(処理順を例えばユーザ別に固めたい場合)
- ジョブ重複実行防止(Amazon SQS に繰り返して投げた場合)
手順
shoryuken sqs create queue.fifo
コマンドで FIFO キュー初期化Shoryuken::Worker
を実装(ActiveJob
も OK!)Shoryuken::Worker.perform_async
やActiveJob.perform_later
でジョブをキューに積むshoryuken -q queue -r ./hello_worker.rb
コマンドでジョブ処理開始
rate limit にでも使える。
Using dry-container to Implement Inversion Of Control for Hanami::Events
Hanami::Events gem 作成者が dry-container の制御の逆転で DB バックエンドのアダプターをカスタムなものでも指定可能にした話。
極秘メソッドの作り方。
.
を含んだメソッド名を define_method('super.secret')
で定義したら、send('super.secret')
でしか呼べないメソッドができる。
考えられる用途:
- 外から使わせたくないメソッド(つまり
private
メソッド) - 名前空間汚染防止
執筆者の注意事項:これやらないほうがいいよ!
Rails 認証セキュリティ改善案 4 つ。
Bundler + GitHub の private リポ上の gem
git://
プロトコール使うな(中間者攻撃脆弱性あり)github:
使うな(裏でgit://
使ってるから)- SSH プロトコールを使う場合は、CI は Machine User の Deploy Key で
- HTTPS プロトコールを使う場合は、Gemfile に Basic 認証のアイパスを埋め込むな。下記のどれかにしろ:
Code
役に立つ awk ワンライナー集 を Ruby で実装してみた。
GraphQL 用認可 gem。CanCanCan、Pundit とも併用可能。