Ruby Weekly #371: 日本語サマリー
職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。
http://rubyweekly.com/issues/371rubyweekly.com
Highlights
Configuring Puma, Unicorn and Passenger for Maximum Efficiency
Puma、Unicorn、Passenger を効率よく設定する方法。
- サーバ毎に 3 子プロセス以上。上限は
(合計 RAM / (あなたのウェブアプリのプロセスの 12 時間経過後の RAM * 1.2))
で計算。 - MRI はサーバ毎に 5 スレッドで良い。JRuby は子プロセス数同様に計算。
- とりあえず preloading オンにしようぜ。
- サーバは RAM 1GB 以上。正確には
5 スレッドの 1 ワーカの 12 時間経過後の RAM * 3
で計算。
時間経過とともに膨らんだ Puma ワーカー。
先月発表された macOS High Sierra 上の Puma 不具合解説。
- macOS が許可している fork 後処理が変わった。
- 許可されてない処理を踏んだアプリサーバが Objective-C エラーを起こす。Objective-C に一切依存していないのに。
- Apple 社が High Sierra の fork 挙動を変えたのは、Objective-C の fork 対応をやりやすくするため。
- Puma などアプリサーバ開発者は、Ruby 言語レベルで対応すべきだと主張してる。
- ワークアラウンドを実装したのは Passenger のみ。
- Puma、Unicorn、iodine ユーザは環境変数指定で一応対応できる。
Ruby メソッドの最も軽量なプロファイリング方法。
- 時間計測は
Time.now
ではなくProcess.clock_gettime(Process::CLOCK_MONOTONIC)
。 - メソッドのパッチは
prepend
ではなくalias_method
。 - スレッドセーフにする必要がある場合は、
Thread.current["hoge"]
でデータ保存。
Passenger 5.1.11 リリース。
「重いよ!」と訴えるユーザに応じて、Jupyter Notebook で Rails ログ可視化手順。
- lograge logstash-event logstash-logger gem でログのフォーマットを JSON に。
- ユーザ ID をスレッドのローカル変数に持たせる。
- Jupyter Notebook の
json_normalize()
関数で Pandas Dataframe にログをインポート。 Dataframe.head
で全体データをサニティーチェック。異常なし。Dataframe.describe
で全体データを集計チェック。異常なし。- 全体データのヒストグラム生成。異常なし。
- ユーザのデータに絞ったヒストグラム生成。異常なし。
- ユーザの 1 秒以上かかったコントローラ・アクションの棒グラフ生成。異常あり。
ROM 4.0.0 リリース。
- rom-repository gem のスキーマ自動マッピング(カラム情報を DB から読み込む機能)が ROM コアにて実装された。
- rom-repository gem の
auto_struct
マッピング(データを Struct に設定する機能)が ROM コアにて実装された。 - カスタム Struct が定義可能に。
changeset
が rom-changeset gem に抽出された。
News
GCP でも AWS でも使える stackdriver gem を紹介した Aja Hammerly 先生。
- Stackdriver Debugger デバッグツール
- Stackdriver Error Reporting 例外モニタリングツール
- Stackdriver Trace パフォーマンスモニタリングツール
- Stackdriver Logging ログ管理ツール
Tutorial
rescue
では例外をちゃんと指定しようぜ、という催促。
rescue Exception
だと、SignalException::Interrupt
までrescue
され、強制終了できなくなっちゃう。rescue => e
だと、予期せぬバグが隠蔽されちゃう。
Using JSON Web Tokens for Authentication in Distributed Systems
分散システム(マイクロサービスなど)の共通認証を JWT で実装する方法。Devise と jwt gem を採用した例。
オブジェクト指向で Rails システムテストを整理する方法。gem なしでページオブジェクトパターンを実装し、partial など共通 UI をモジュールに抽出している。
MongoDB が用途に合わなくなった Contractually 社がダウンタイムなしで PostgreSQL にデータを移行した 3 ステップ戦略。
- 第 1 デプロイ:稼働中のデータを MongoDB にも PostgreSQL にも WRITE。READ は MongoDB から。
- Mongoid のコールバックで PostgreSQL に書き込むバックグラウンドジョブをキューに積む。
- 12〜36 時間で移行完了の想定。
- 第 2 デプロイ:稼働中のデータの READ も WRITE も PostgreSQL から。
- NewRelic でパフォーマンス・エラー発生率監視。
- 第 3 デプロイ:Mongoid、MongoDB 削除。
- 予めバックアップ。
Array#zip
活用案いろいろ。
- 2 つの配列を比較する。
- 2 つの配列の各インデックスの最大値を取得する。
- キーの配列と値の配列を結合してハッシュを作る。
Enumerable#count
とチェーンして同一要素を数える。- シーザー暗号を実装する。
ホテルを例に挙げたコマンドパターン解説。
- 宿泊客がルームサービス、ランドリー、観光地パンフレットをコンシエルジュに注文。
- コンシエルジュが注文を厨房、クリーニング作業員、ベルボーイに依頼。
そのまま実装すると Concierge
オブジェクトにキモい case
文ができてしまう。各注文をコマンドオブジェクトにすることで、Concierge
がロジック分岐せずに実行できるようになる。おまけに
Concierge
以外のオブジェクトにも引数として渡せる。- 注文をキューに積むことができる。
- 注文をログに残すことができる。
- 注文を巻き戻すことができる。
Virtus gem のフォームオブエクトでデータをサニタイズする例で、Virtus::Attribute#coerce
でホワイトスペースを文字列から消してる。
プロジェクト管理ツールの UI をリアルタイムで更新するための ActionCable 実用ガイド。Build A SaaS App in Rails 5 本の抜粋。
関数型プログラミングをずっと警戒してた Rubyist をやっと説得できたリンク 3 つ。
- Ruby のオブジェクト指向と関数型プログラミングを融合した、dry-rb コアチームの Piotr Solnica 先生のトーク
- dry-rb コアチームの Tim Riley 先生のブログシリーズ
- Hanami 作成者 Luca Guidi 先生のトーク
Code
請求書 PDF 生成用 InvoicePrinter gem。 見辛い Prawn コードをカプセル化したのが売り。
Hanami v1.1.0.rc1 リリース
Ruby Weekly #370: 日本語サマリー
職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。
Highlights
do; end
ブロック内rescue
対応。yield_self
新規追加。- bundler 同梱。
- 同一ネームスペース内で見つからなかった定数をルートネームスペースから探すのがなくなった。
RubyGems シリアライゼーション脆弱性を解説した Aaron Patterson 先生。 gem のチェックサムが YAML で保存されているのが原因。 RubyGems.org はこの脆弱性で攻撃された痕跡はない。 シリアライズ可能なオブジェクトをホワイトリストすることで解消済み。
レポート用 Rails engine。
Introducing hanami-cli: A New Framework for Command Line Tools
hanami-cli を紹介した、Hanami 作成者 Luca Guidi 先生。 thor では実装しづらい下記機能がある:
- サブコマンド。例えば
$ hanami generate action
のgenerate action
。 - 拡張性。外部 gem が Hanami にサブコマンドを追加できるようになった。
Hanami じゃなくても使えるので、thor の代替案として考えれば良い。
同一ネームスペース内で見つからなかった定数をルートネームスペースから探すのが Ruby 2.5 からなくなった。その経緯を語る Redmine チケット。
Surrealist gem に対応するように、Array
と ActiveRecord::Relation
のモンキーパッチを検討した話。
下記条件全部満たせなければ、モンキーパッチやめたほうがいいと。
- これ以上のモンキーパッチはない。
- モンキーパッチしたコードに依存しているものが壊れない。
- モンキーパッチ以外の選択肢がない。
- 新しいインタフェースが作れない。
カンファレンスを初めて主催した経験談。地方カンファレンスがなくなってきたのがきっかけ。
- 昔あったナッシュビル市の Ruby Hoedown カンファレンス主催者から許可を得た。
- ドメイン取得(自腹)。
- 会社設立(自腹)。
- ロゴ発注(自腹)。
- キーノート登壇者を招待した。
- CFP を 1.5 ヶ月開催。もうちょっと長くすればよかった。
- 予算計算。$199 のチケットを 175 枚売れば黒字。
- 会場探し。
- スポンサー探し。大変だったため、プランはもうちょっと安くすればよかった。
- 登壇者宿泊 + 交通費負担することにした。
- チケット発売。SNS + Ruby Flow + Reddit で宣伝。87 枚売れた。
- カンファレンス 3 日間開催。
赤字だったが、Ruby コミュニティに貢献できた充実感で、来年も開催予定!
News
Rails 5.2 では、暗号化・署名付きクッキーの有効期限が設定可能に。
台北の RubyElixirConf Taiwan 2018、CFP 開始。
Mastering Ruby: Strings and Encodings 本発売。
Tutorial
Receiving and Parsing Email in Rails 5 Using Griddler and Mailgun
Build a SaaS App in Ruby on Rails 5 本の抜粋。Rails 5 + Griddler + Mailgun でメールを受信・パースする手順。
- ngrok で手元マシンへの URL を用意。
- Mailgun で受信したメールを ngrok URL に転送するように Mailgun を設定。
- Griddler gem を Rails アプリにマウント。
EmailProcessor
オブジェクトでパース・処理を実装。
Rails 5.2 の HTTP2 Early Hints を発表した Eileen Uchitelle 先生。Rails がレスポンスを 2 つ返すようになる:
- Early Hints(HTTP ステータス 103)
- 通常のレスポンス(HTTP ステータス 200、404、500 など)
Early Hints はブラウザーが優先的にダウンロードするファイル(JavaScript、CSS など)の指定。Rails での検証手順も記載されてる。
Ruby 2.5 スタックトレースの見た目改善。エラー発生行番号が一番下になった。長いスタックトレースの上までスクロールすることがなくなって便利。しかし Rails・RSpec では効かない。
巨大メソッドをクラスに抽出した話。
Ruby のよく知られてないメソッド。
Integer#digits
(Ruby 2.4 以降)#tap
Array#values_at
Hash#transform_values
(Ruby 2.4 以降)Kernel#itself
(Ruby 2.2 以降)Array#count
Enumerable#cycle
Paperclip で Rails GraphQL API から画像を S3 にアップロードした話。REST アプリならドキュメンテーションはいっぱいあるが、GraphQL アプリは一切ない。画像を Base64 文字列に変換してから mutation の引数として Paperclip に渡した。
HexaPDF gem の PDF ファイル読み込み処理解説。
- PDF ファイルは不特定多数のストリームで構成されてる
- 各ストリームには不特定多数のフィルターが指定されてる
- フィルターはストリームデータの解読方法を定義している(例:JPEG 画像は
DCTDecode
フィルター、ASCII 文字列はASCIIHexDecode
フィルター) - フィルターはそれぞれ
HexaPDF::Filter::ASCIIHexDecode
のようなモジュールで実装されてる - ストリームは
HexaPDF::StreamData
オブジェクトでカプセル化 - ストリームのデータは非同期で読み込むため、Ruby の Fiber 採用
Rails フォルダー構造まとめ。
RSpec で深階層の nested attributes を指定した話。手で組み立てるのが大変だった。先輩に相談したら、ログからコピペすることになった。
Tools
nullalign: Generate Warnings for Missing Not-Null Constraints
NOT NULL
制限のない validates presence: true
を検知してくれる nullalign gem。
Code
ActiveRecord + PostgreSQL 10 パーティション管理用 gem.
Ruby Weekly #369: 日本語サマリー
職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。
Highlights
Symbol
と String
の不一致がバグの根源なので、Ruby から Symbol
を捨てないかという提案。
- 下位互換性を維持するには、
Symbol
を#freeze
したString
にすれば良い。 Symbol#to_s
から#freeze
されてないString
を返すようにする。#hash
を同等にする必要がある。Symbol#hash
計算が 2〜3 倍速いから、String#hash
計算もSymbol#hash
に合わせたい。
Fixnum
Bignum
捨てたし、Symbol
も捨てれるのでは?と。
Ruby Rogues の Charles Max Wood 先生主催の Ruby Dev Summit 分散型カンファレンス(物理的開催地はなく、参加者はみんな動画配信やチャットで交流・登壇)。
get_schwifty: Render Portions of Rails Views in a Background Job Queue
重い partial を ActiveJob で render、ActionCable でブラウザー上非同期描画する gem。
株式会社デジカの Chris Salzberg 氏が RubyKaigi でトークを発表した話。たまたま Matz のキーノートと同じく、モジュールを題にしてた。しかし「モジュールはクラスではない」と言わんばかりの Matz 発言が Salzberg 氏のトークと矛盾してたのでちょっと困った。Module
は Class
だからこそ Ruby ならではの Module Builder パターンが可能。
-rubygems
に対応するための ubygems.rb
が削除された、というちょっと面白いコミット。
Gusto 社の給与システムが関数型 Ruby になるようにリファクターした話。
- PFaaO パターンで純粋関数オブジェクトを実装した。給料計算関数オブジェクトを例として挙げた。
- 純粋関数オブジェクトなので、メモ化していても参照透過性が維持されてる。
- 給料計算関数オブジェクトの中の税金計算メソッドを税金計算関数オブジェクトに抽出した。
- ActiveRecord モデルそれぞれに対して immutable な Value Object を切って、純粋関数オブジェクトにValue Object のほうを渡すようにした。
News
Hanami v1.1.0.beta2 リリース翌日に、バグ解消で v1.1.0.beta3 リリース。
Tutorial
Surrealist: A Gem to Serialize Ruby Objects According to a Defined Schema
シリアライズ用スキーマ定義 surrealist gem の紹介。データ型定義やキー camelize 機能など込み。
- Angular プロジェクトの該当 directive ファイルを開く関数
Ruby コアの delegate.rb をコードリーディングした話。
Delegator
が継承しているのは、不要なメソッドを省略されたKernel
。#initialize
#method_missing
メソッドはDelegator
にて実装されている。- デリゲート先オブジェクトの accessor は
SimpleDelegator
など子クラスで実装されている。 #method_missing
がチェックするのはデリゲート先オブジェクトと一部省略したKernel
。
Hash#fetch
でデフォ値を返すようにする。ブロック渡せば遅延評価もできる。
筆者著作の Domain-Driven Rails 本の抜粋。メソッドを 2 つのメソッドに分解することで Event Sourcing するというルールの解説。2 つのメソッドとは:
- イベントを発行するメソッド
- イベントの効果を適用するメソッド
Ruby 配列いろいろ
#initialize
方法いろいろ#slice
方法いろいろ#insert
方法いろいろ<=>
挙動|
挙動&
挙動
Ruby 2.4 では Enumerable#min
Enumerable#max
Enumerable#minmax
が速くなった!
validate uniqueness:
使用時の高速化案。
筆者作品の UniqueValidationInspector gem では、インデックスのない validate uniqueness:
を検知できる。
Ruby バージョン確認方法まとめ
環境 | 確認方法 |
---|---|
irb | RUBY_VERSION |
rvm | rvm current |
rbenv | rbenv version |
コマンドライン | ruby -v |
コマンドライン | which ruby |
コマンドライン | gem env |
Story
A Reddit AMA with the Authors of 'Effective Testing with RSpec 3'
Effective Testing with RSpec 3 著者たちの質疑応答 Reddit スレ。
Python コードのパフォーマンスを最適化した Richard Schneeman 先生。
Ruby との共通ルール:
- ダブってるロジックを省けば軽くなる。
- オブジェクトのインスタンス化を省けば軽くなる。
- オブジェクトのシリアライズを省けば軽くなる。例:シリアライズした配列を引数として渡すよりも、要素を渡したほうが軽い。
- ループ内のリテラルを省けば軽くなる。リテラル=オブジェクトのインスタンス化なので。
- 不要なロジックを省けば軽くなる。あり得ない
if
文の分岐点など。 - メソッドを省けば軽くなる。効果はそんなに大きくないので、このルールに関しては無理しなくて良し。
- ベンチマーク必須。
- キャッシュするなら、オブジェクトのインスタンス化ルールは破って良し。
レガシー Rails アプリに呆れて、18 ヶ月も Rails を避けていた経験で得た知見。
- 悪いのは Rails 自体ではなく、Rails の用途に合わないアプリ
- 何でも gem に依存させるのも良くない
- Rails はドキュメンテーションが充実してる
Opinion
default_scope
ではなく明示的に scope
使おうという主張。
new
したモデル属性はdefault_scope
で設定されちゃうのが予期せぬバグの元。default_scope
を外すことは辛い。unscoped
だとアソシエーションのスコープまで外れちゃったりするから。
Tools
Ruby 上級者向け書籍。
- オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方
- Rubyのしくみ -Ruby Under a Microscope-
- Effective Ruby
- Ruby Way 第2版 (Professional Ruby Series)
- Mastering Ruby Closures: A Guide to Blocks, Procs, and Lambdas
- Rails, Angular, Postgres, and Bootstrap: Powerful, Effective, Efficient, Full-Stack Web Development
- Service-Oriented Design with Ruby and Rails (Addison-Wesley Professional Ruby Series)
Code
render_async 1.0: Render View Partials Asynchronously via Ajax
Rails ビューの partial を AJAX で非同期ロードする gem。
Bing Maps API クライアント用 gem。
Ruby Weekly #368: 日本語サマリー
職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なあらすじを書くようにしています。そのあらすじをここでまとまさせていただきます。くだけた日本語で失礼いたします。
Highlights
Aaron Patterson 先生が Ruby ヒープを可視化した話。ObjectSpace
でヒープを JSON で取得し、ChunkyPNG
で PNG 画像に落とした。
Ruby 2.5 の Object#yield_self
登場。Elixir の |>
演算子相当。筆者見解では、コードのフロー的には読みやすくなるが、ボイラープレートが多い。
@schneems 先生の外国人として RubyKaigi に参加する豆知識。
- 内容はテクニカルもの重視。スライドはコード大量。
- 日本語トークはイヤホンで同時通訳あり。
- トーク後の質疑応答は、司会が頑張って通訳。
- 英語トークよりも日本語トーク聞いたほうがいい。あとからアップロードされる動画には字幕・吹替がないから。
- 英語圏のいわゆる hallway track (参加者同士の交流)は基本ない。日本人は真っ赤の他人に話しかけたり質問したりするのに抵抗があるから。
- 日本のレストランが狭くて大人数で食事するのが難しい。10 人座れるのは居酒屋ぐらい。そして居酒屋はあまり美味くない。
- 食事の相手は日本語が喋れる人がいれば非常に助かる。美味い店は英語のできない店が多いから。
- Yelp はあるが、tabelog 使いましょう。
- コンビニ飯は意外と美味い。
日本人参加者へのお願い:外国人参加者に積極的に話しかけてください!
Thoughtbot 社員がテスト高速化のためにデバッグした話。
- spec_helper.rb 部分的コメントアウトで下記犯人が判明:
- 全テスト用の
config.before(:each)
に feature テストのセットアップが入ってた。type: :feature
などのメタタグで用途別に分けた。 - 全テスト
DatabaseCleaner.strategy = :truncation
になってた。メタタグで:truncation
:transaction
適用した。
- 全テスト用の
- FactoryGirl 部分的コメントアウトで
after(:create)
のレコード大量作成が判明。trait
に移し、再発防止として ActiveSupport Instrumentation でレコード作成数を見える化した。
Ruby 3x3 ベンチマークとして作られた NES エミュレーター OptCarrot の紹介。
Using Python's scikit-learn Machine Learning Library via PyCall
PyCall gem 経由で Python の scikit-learn 機械学習ライブラリーを Ruby から呼ぶ手順。
News
サポート終了済みの Rails 4.2 は、デグレ対応のため 4.2.10 リリース。
macOS High Sierra の fork 挙動が変わったため、Puma ワーカーが失敗する現象発覚。
未解消!
Tutorial
#eql?
#hash
のモンキーパッチで
- 異なるキーで同一値のハッシュ
- 同一キーで異なる値のハッシュ
- 時間限定キーのハッシュ
をインスタンス化した話。Fixnum
、String
、Symbol
は C レベルで塞がれているが、それ以外のオブジェクトはモンキーパッチできた。
良い子は真似しないでね。
Object#try
が有害だという主張。オブジェクトがヌルな場合でも、メソッドが定義されていない場合でも、エラー投げずにヌルを返し、正当なエラーまで隠滅してしまうから。
代替案:
- ヌルチェックを明示的な
if
文で。 - デメテル法則厳守。
- DB レベル
NOT NULL
でヌルを防ぐ。 - 暗黙の
to_s
などに頼らず、明示的に該当データ型に変換。 - ダックタイピング。
- ヌルオブジェクトパターン。
&.
は OK。ヌル以外のオブジェクトでメソッドが定義されていない場合はNoMethodError
を投げるから。
crontab + whenever gem で Sidekiq ジョブを定期的に起動する手順。
graphql gem で Rails アプリの GraphQL API を実装した話。
How To GraphQL チュートリアルも参考に。
Rails 5.1 で React のアイデア付箋 CRUD アプリの実装手順。
- Rails API 実装。
- Facebook 社の Create React App で新規 React アプリ生成。
IdeasContainer
IdeaForm
などコンポーネント実装。- NPM の axios ライブラリで API を叩く。
- rack-cors gem で CORS 制限解消。
- NPM の immutability-helper ライブラリで React 上データのイミュタブル性を保証しながら更新。
- React Developer Tools ブラウザー拡張で状態監視。
link_to
などにパスを指定する方法いろいろ。
edit_admin_exercise_path
edit_admin_exercise_path
ヘルパー[:edit, :admin, exercise]
配列{action: :edit, controller: "admin/exercises", id: exercise.id }
ハッシュ/admin/exercise/5/edit
文字列ハードコード
PDF 非同期生成の生成完了通知を ActionCable で実装した話。Michael Hartl 先生の Learn Enough Action Cable to Be Dangerous を参考にしていた。
Ruby 感情分析ツールまとめ。
- sentimental gem: 辞書ベース
- sentimentalizer gem: 機械学習ベース
- Ankusa gem: ベイズ分類器ベース
- Hoatzin gem: SVM 分類器ベース
- Classifier gem: SVM 分類器ベース
- Eluka gem: SVM 分類器ベース
- Tensorflow Ruby API
Ruby Weekly #367: 日本語サマリー
職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。
Highlights
Ruby ツールまとめ。
mutant gem のミュテーションテストでモジュールの設計を見直した話。mutant が @unpublished_events = []
を @unpublished_events = nil
に変えたのに、テストがそのまま通った。原因は getter がメモ化していたから。getter が必要なののは、#initialize
で設定していないから。#initialize
を prepend してみたが、無理矢理すぎて結局何も変えないことにした。
Crystal はシンタックスが Ruby に非常に似ていてかつ速い。筆者のスクリプトも Crystal が 80 倍速かった。
Crystal の特徴:
- Type Union: 1 つの変数で複数データ型を許容できる
- Type Inference & Checking: コンパイル時にデータ型チェック・推論
- Concurrency: Fiber に対応しているが、マルチスレッドはこれから
- マクロでメタプロ
- Ruby からも呼べる
Google 社員の Aja Hammerly 先生がアヤメのデータセットで k 近傍法を紹介。アヤメのデータセットを散布図でプロット。品種の不明なアヤメの花もプロットしたら、図上距離の最も近いものが同一品種だと推測できる。図上距離はピタゴラスの定理で計算。
News
Tutorial
Rails で Webhook を実装する手順。
- 送信先 URL と該当イベントのマッピングを保存する
Webhook::Endpoint
モデルとwebhook_endpoints
テーブル。 - イベントとペイロードデートをラッピングする
Webhook::Event
モデル。 - 各モデルに include する
Webhook::Delivery
モジュール。モデルのコールバックでWebhook::Delivery#deliver_webhook
を呼ぶ。 - 非同期送信用
Webhook::DeliveryWorker
をWebhook::Endpoint#deliver
から呼ぶ。
Build Your Own Daily Fantasy Football Salary Tracker with Ruby and Twilio
Ruby でファンタジーフットボール用選手給料トラッカーを作った話。 ファンタジーフットボールとは米国大人気のアメフトのドラフト会議シミュレーションゲーム。 リアル選手のリアル給料に大きく影響されるので、 2 時間ごとに最新給料 CSV を DraftKings.com からダウンロードして DB に保存。 変動のあった給料を ImageMagick で画像に描画し、Imgur にアップロード。 Twilio で Imgur リンクを MMS として携帯に送信。
TTY::Command gem でシェルコマンドを細かく制御。system
、...
だけでは、下記よくあるニーズが満たせない。
- exit ステータスが 0 以外の場合は例外を投げる
- stdout、stderr 抑えて、文字列に格納して返して欲しい
Open3#popen3
なら細かく操作できるが、低レベルで使いづらくてミスりやすい。
- HTML エスケープを止める
raw
、html_safe
や ERB の<%== %>
。 - HTML 属性の
"
漏れ。 link_to
の URL。- テンプレート内 JSON。Rails は
json_encode
推奨。 - コントローラで
render inline:
。サーバ上シェルコマンド実行までできちゃう!
DateTime#to_time and Time#to_time Preserve Timezone in Ruby 2.4+
Ruby 2.4 以降の DateTime#to_time
Time#to_time
がタイムゾーンを維持するようになった。2.3 以前はシステムタイムゾーンに変更していた。
カスタム matcher BeEvent
に RSpec::Matchers::Composable
を include
することで
expect([FooEvent.new, BarEvent.new]).to include(an_event(BarEvent)) expect(domain_event).to be_an_event(OrderPlaced).with_data(order_id: kind_of(Integer))
のような expectation を実現した話。
metrics_tracker
ローカル変数の定義までトランザクションのブロックに囲ってしまったら、ブロック外で metrics_tracker
の呼び出しでバグを起こした話。
メールで送るパスワードリセット用リンクなどのトークンを生成・検証してくれる ActiveSupport::MessageVerifier
の実用例。トークンは DB に保存しないためセキュリティ抜群。
Tools
ezpaas-cli: A Miniature Docker-Powered Heroku Clone for In-House Deployments
Heroku の OSS クローン。動的インスタンスは Docker で。
Python → Ruby 変換用 Python スクリプト。
Code
Sequel ORM 生みの親 Jeremy Evans 先生の routes 用 gem Roda 3.0 がリリースされた。
Ruby Weekly #363: 日本語サマリー
職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。
Highlights
Ruby 並行処理まとめ
- プロセス。多数コア使えるが、fork が重い。
- スレッド。プロセスより軽量だが、管理が複雑。競合状態防止とかの。
- EventMachine gem。スレッド管理してくれるが、コールバックが複雑。
- Fiber。EventMachine のコールバックを隠してくれる。
並行処理方式 | サーバ例 | バックグラウンドジョブ例 |
---|---|---|
プロセス | Unicorn | Resque |
スレッド | Puma | Sidekiq |
EventMachine | Goliath | AMQP |
この 5 メソッド活かそうぜ!
Object#tap
Array#bsearch
Enumerable#flat_map
- ブロック付き
Array.new
<=>
Ruby の紛らわしい 6 機能
[]
メソッド。Array にも Hash にも String にも Proc・lambda にも付いてて諸悪の根源だと筆者が主張。%
演算子。剰余演算子にもなれば、文字列のフォーマット演算子にもなる。Integer#zero?
メソッド。== 0
のほうが無難。$数字
グローバル変数。Time.parse
。不正な文字列渡しても、不正な部分だけTime.now
で埋め込んじゃうという時限爆弾。Delegator
OSS の EC サイト用 Rails アプリ Spree 3.3 リリース
Using ActionCable and RethinkDB to Build a Reactive WebSocket App
ActionCable + RethinkDB でスプレッドシート実装。 RethinkDB の ORM として NoBrainer gem 採用。
- 各ユーザの選択中セルの枠に違う色を付けて Publish
- セルの中身を永続化して Publish
- 編集中セルにロックをかけて Publish
ActiveRecord トリック 5 点
join
の条件はscope
をmerge
しようjoin
は普段INNER JOIN
になるんだが、ネストするとLEFT OUTER JOIN
になることもあるので要注意EXISTS
、NOT EXISTS
は便利メソッドで- サブクエリは
pluck
悪用せずに ActiveRecord に任せよう to_sql
、explain
活かそう
News
Passenger 5.1.8 Released: Nginx 1.12.1, Webpacker, and Fixes
Passenger 5.1.8 リリース
- apt-get パッケージがやっとバージョンアップ(1.10.3 以降はできてなかった)
- webpacker 対応
- 冗長なログが見やすく
Tutorial
Factory と Fixture の力を合わせて外部 API を擬似化。eBay の巨大 XML レスポンスを例に挙げた。XML の Fixture を Factory に読み込み、Hash に変換。
Ruby コアのスレッド間データ通信クラスまとめ。Queue#push
でデータを積むと、別スレッドの Queue#pop
でそのデータが取得できる。上限付きキューは SizedQueue
で。
Adding Token Based Auth to a Rails API with Devise Token Auth
Devise Token Auth gem で Rails API のトークンベース認証を実装する手順。
Hanami のレビュー。
- Generator 完備
- Migration 完備
- Shotgun gem で code reloading 完備
- モデル層が Entity と Repository に分かれてる
- コントローラ層は 1 アクション = 1 クラス
- ビュー層は Template と View に分かれてる
感想
- 😄 アーキテクチャ構造が整理整頓
- 😢 ドキュメンテーション不足
- 😢
db:seeds
がない - 😢
belongs_to
has_one
がない(先週発表したように v1.1.0β1 ではリリース済み)
Rails 5.1 で AJAX を使う方法 3 通りとそれぞれの導入手順。
===
いろいろ
- クラス・モジュールを被演算子にした場合は
kind_of?
- 正規表現を被演算子にした場合は
=~
Range
を被演算子にした場合はその範囲内Proc
を被演算子にした場合はcall
- それ以外のオブジェクトを被演算子にした場合は
==
Tools
Ruby Tests Profiling Toolbox: Tools to Analyze Test Suite Performance
先週にも紹介された TestProf メトリックス計測ツール群。
Code
clone、カスタマイズ用の Sinatra + GraphQL 骨組みアプリ。Trailblazer、Apollo、React も込み。
ファジーマッチング用 gem。類似比較で使えるハッシュ値を生成してくれる。
ActiveRecord ログの SQL にコントローラやアクションなどのコメントを添える gem。Basecamp 作品。
ジオコーディング用 gem。住所で経度・緯度を算出し、その逆の照合も可能。
Ruby Weekly #362: 日本語サマリー
職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。
Highlights
メトリックス計測ツール群 TestProf でテスト最適化。
- TagProf で重いテスト特定
- RubyProf、StackProf と併用して重いスタック特定
- EventProf で DB 処理の重いテスト特定
- EventProf で重いバックグラウンドジョブ特定
- FactoryGirl の不要なデータ作成を FactoryDoctor で特定
- RSpecStamp で動的に不合格テストにタグを張る
N+1 クエリ撲滅方法比較
preload
- 2
SELECT
eager_load
- 1
LEFT OUTER JOIN
joins
- 1
INNER JOIN
includes
- Rails 4 以前は、魔術で
preload
eager_load
joins
の中からベストを選択してくれた - Rails 5 以降は、
includes
=preload
。references
でJOIN
を強制させる(魔術の保守を諦めたコアチーム)
Q 学習アルゴリズムを Ruby で実装して、ゲームの AI を学習させた話。
synvert gem で
flash[:notice] = "Hoge" redirect_to root_path
の古い表記をよりなうい
redirect_to root_path, notice: "Hoge"
に書き換えた話。
好きな OSS リポから Issue を割り振ってくれるサービス CodeTriage。@schneems さんのバグでユーザに巨大メール送っちゃった話。
SendGrid の上限を超えちゃったある日。冪等になってなかった割り振るジョブが落ち、一時間ごとにリトライを繰り返した。SendGrid に追加課金した途端に、各ユーザの溜まった 400 以上もの Issue をメールで飛ばしちゃった。
Evented Rails: Decoupling Complex Domains in Rails with Events
イベント駆動 Rails で DDD の Bounded Context を疎結合に。
配車サービスを例に挙げ、密結合した 配車依頼 → 自動車マッチング → 依頼主・運転手通知
機能を Wisper gem の pub/sub で 依頼主
コンテキストと マッチング
コンテキストを分離した。
News
Rails コアチーム新メンバー
Tutorial
N+1 クエリ解消策には eager loading、preloading のほかに バッチング策
もあった。筆者が Facebook の Haskell 制 Haxl ライブラリに倣って BatchLoader gem を作った。並列処理、GraphQL を活用例として挙げた。スレッドセーフでキャッシング完備。
イベントのチケット販売アプリのリマインダー通知を再起計算でスケジューリングした話。チケット購入直後とイベント開始直前のリマインダーは頻繁に、その間はもっと永い間隔で。
RSpec のブートを 50 倍速くした話。答えは spring。rvm のローカル gemset を最低限に減らしても大差はなかった。
ポリモーフィック関連付けの解説。レストランのレビューとイベントのレビューを表す Review モデルで例を挙げた。
Builder デザインパターンを Ruby で実装。ここであらすじ書かなくても原文のコードは読みやすくて分かりやすい! ★★★
Rails 5.1 の暗号化 Secret。
bin/rails secrets:setup
で下記ファイル生成:
- config/secrets.yml.key(キーファイル。コミットするな!絶対に)
- config/secrets.yml.enc(暗号化 Secret ファイル)
bin/rails secrets:edit
で修正。
キーファイルをサーバに置く方法:
- scp/sftp
RAILS_MASTER_KEY
環境変数
Story
Heroku CLI の進化。
v1〜v3
v4
- Go + Node
- Go だけでは動的ライブラリに対応できなかったので、プラグイン機能は Node で
- CLI コアまでプラグインに抽出
- 初回実行で Node + コアプラグインをダウンロード
- 2 年間じっくりかけた
v5
- Go + Node
- Node + コアプラグインを tarball に同梱
v6
- Node のみ
- Go を捨てた理由
- OS アップデートで Go 周りぶっ壊れる
- Go は比較的低レベルで、機能追加がしんどい
- プラグイン参照するたびに新規 Node プロセスを切るのに数百ミリ秒もかかった
- CLI フレームワーク cli-engine 抽出、OSS 化
- プラグインのインタフェースを ES6 に
- Node 7 の
async
/await
活用 - コア・プラグイン開発は
Tools
Fabrication vs FactoryGirl ベンチマーク。ネストしているモデルの場合は、Fabrication のほうが速い。create
は特に。
Code
新機能
belongs_to
、has_one
、has_many :through
アソシエーション- thor 捨てて hanami-cli gem 新規作成
- Entity のマニュアルスキーマ定義(ActiveModel の属性定義に相当)
- CLI からブートするアプリ指定
- ログの機密情報マスク(Rails の
filter_parameters
に相当)
DDOS 防止 Rack::Attack
gem
システムステータス告知用 Rails アプリ
bettercap: A Modular, Portable and Extensible MITM Framework
中間者攻撃用 gem。脆弱性検証でも使えるらしい。
k 近傍法による分類用 gem(機械学習)