rastam on rails

東京在住のマレーシア人 Rubyist

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 ワーカー。

Why Ruby App Servers Break on macOS High Sierra

先月発表された macOS High Sierra 上の Puma 不具合解説。

  • macOS が許可している fork 後処理が変わった。
  • 許可されてない処理を踏んだアプリサーバが Objective-C エラーを起こす。Objective-C に一切依存していないのに。
  • Apple 社が High Sierra の fork 挙動を変えたのは、Objective-C の fork 対応をやりやすくするため。
  • Puma などアプリサーバ開発者は、Ruby 言語レベルで対応すべきだと主張してる。
  • ワークアラウンドを実装したのは Passenger のみ。
  • Puma、Unicorn、iodine ユーザは環境変数指定で一応対応できる。

Fastest Way to Profile a Method in Ruby

Ruby メソッドの最も軽量なプロファイリング方法。

  • 時間計測は Time.now ではなく Process.clock_gettime(Process::CLOCK_MONOTONIC)
  • メソッドのパッチは prepend ではなく alias_method
  • スレッドセーフにする必要がある場合は、Thread.current["hoge"] でデータ保存。

Passenger 5.1.11 Released: A Key Security Release

Passenger 5.1.11 リリース。

  • システムフィアルが一覧表示できちゃう脆弱性対応
  • macOS High Sierra 対応
  • HTTP/2 対応
  • 遅延ポートバインディング用オプション追加
  • root 権限チェック・忠告追加

Visualizing Rails Logs With Jupyter Notebook

「重いよ!」と訴えるユーザに応じて、Jupyter NotebookRails ログ可視化手順。

  1. lograge logstash-event logstash-logger gem でログのフォーマットを JSON に。
  2. ユーザ ID をスレッドのローカル変数に持たせる。
  3. Jupyter Notebook の json_normalize() 関数で Pandas Dataframe にログをインポート。
  4. Dataframe.head で全体データをサニティーチェック。異常なし。
  5. Dataframe.describe で全体データを集計チェック。異常なし。
  6. 全体データのヒストグラム生成。異常なし。
  7. ユーザのデータに絞ったヒストグラム生成。異常なし。
  8. ユーザの 1 秒以上かかったコントローラ・アクションの棒グラフ生成。異常あり。

ROM 4.0.0 Released: The Ruby Object Mapper

ROM 4.0.0 リリース。

  • rom-repository gem のスキーマ自動マッピング(カラム情報を DB から読み込む機能)が ROM コアにて実装された。
  • rom-repository gem の auto_struct マッピング(データを Struct に設定する機能)が ROM コアにて実装された。
  • カスタム Struct が定義可能に。
  • changesetrom-changeset gem に抽出された。

News

Monitor, Debug and Log Your Ruby Apps with Stackdriver

GCP でも AWS でも使える stackdriver gem を紹介した Aja Hammerly 先生。

Tutorial

Rescue Specific Errors. Avoid Rescuing StandardError

rescue では例外をちゃんと指定しようぜ、という催促。

  • rescue Exception だと、SignalException::Interrupt まで rescue され、強制終了できなくなっちゃう。
  • rescue => e だと、予期せぬバグが隠蔽されちゃう。

Using JSON Web Tokens for Authentication in Distributed Systems

分散システム(マイクロサービスなど)の共通認証を JWT で実装する方法。Devisejwt gem を採用した例。

OOP and Rails System Tests

オブジェクト指向Rails システムテストを整理する方法。gem なしでページオブジェクトパターンを実装し、partial など共通 UI をモジュールに抽出している。

Migrating Data From MongoDB to Postgres with No Downtime

MongoDB が用途に合わなくなった Contractually 社がダウンタイムなしで PostgreSQL にデータを移行した 3 ステップ戦略。

  1. 第 1 デプロイ:稼働中のデータを MongoDB にも PostgreSQL にも WRITE。READ は MongoDB から。
    • Mongoid のコールバックで PostgreSQL に書き込むバックグラウンドジョブをキューに積む。
    • 12〜36 時間で移行完了の想定。
  2. 第 2 デプロイ:稼働中のデータの READ も WRITE も PostgreSQL から。
    • NewRelic でパフォーマンス・エラー発生率監視。
  3. 第 3 デプロイ:Mongoid、MongoDB 削除。
    • 予めバックアップ。

What Can You Do with The Array#zip Method?

Array#zip 活用案いろいろ。

  • 2 つの配列を比較する。
  • 2 つの配列の各インデックスの最大値を取得する。
  • キーの配列と値の配列を結合してハッシュを作る。
  • Enumerable#count とチェーンして同一要素を数える。
  • シーザー暗号を実装する。

The Command Pattern in Ruby

ホテルを例に挙げたコマンドパターン解説。

  1. 宿泊客がルームサービス、ランドリー、観光地パンフレットをコンシエルジュに注文。
  2. コンシエルジュが注文を厨房、クリーニング作業員、ベルボーイに依頼。

そのまま実装すると Concierge オブジェクトにキモい case 文ができてしまう。各注文をコマンドオブジェクトにすることで、Concierge がロジック分岐せずに実行できるようになる。おまけに

  • Concierge 以外のオブジェクトにも引数として渡せる。
  • 注文をキューに積むことができる。
  • 注文をログに残すことができる。
  • 注文を巻き戻すことができる。

Sanitize Attributes Through Your Form Object with Virtus

Virtus gem のフォームオブエクトでデータをサニタイズする例で、Virtus::Attribute#coerce でホワイトスペースを文字列から消してる。

A Practical Guide to Using ActionCable

プロジェクト管理ツールの UI をリアルタイムで更新するための ActionCable 実用ガイド。Build A SaaS App in Rails 5 本の抜粋。

Exploring Functional Programming with Ruby

関数型プログラミングをずっと警戒してた Rubyist をやっと説得できたリンク 3 つ。

  1. Rubyオブジェクト指向関数型プログラミングを融合した、dry-rb コアチームの Piotr Solnica 先生のトーク
  2. dry-rb コアチームの Tim Riley 先生のブログシリーズ
  3. Hanami 作成者 Luca Guidi 先生のトーク

Code

InvoicePrinter 1.0: PDF Invoice Generation from Ruby

請求書 PDF 生成用 InvoicePrinter gem。 見辛い Prawn コードをカプセル化したのが売り。

Karafka: A Ruby Framework for Working with Apache Kafka

Kafka + Ruby アプリ用 MVC フレームワーク

Hanami 1.1.0.rc1 Released

Hanami v1.1.0.rc1 リリース

  • アソシエーションの alias 定義可能に belongs_to :user, as: :author
  • カスタムスキーマのデータ型を任意 Entity で設定可能に
  • hanami generate model コマンドの新規オプション --relation (テーブル名)
  • RSpecメタデータ追加

Ruby Weekly #370: 日本語サマリー

職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。

rubyweekly.com

Highlights

Ruby 2.5 Preview 1 Released

Ruby 2.5 Preview 1 リリース!

  • do; end ブロック内 rescue 対応。
  • yield_self 新規追加。
  • bundler 同梱。
  • 同一ネームスペース内で見つからなかった定数をルートネームスペースから探すのがなくなった。

Unsafe Object Deserialization Vulnerability in RubyGems

RubyGemsリアライゼーション脆弱性を解説した Aaron Patterson 先生。 gem のチェックサムYAML で保存されているのが原因。 RubyGems.org はこの脆弱性で攻撃された痕跡はない。 シリアライズ可能なオブジェクトをホワイトリストすることで解消済み。

ReportsKit: Add Reporting to Your Rails App in Minutes

レポート用 Rails engine。

Introducing hanami-cli: A New Framework for Command Line Tools

hanami-cli を紹介した、Hanami 作成者 Luca Guidi 先生。 thor では実装しづらい下記機能がある:

  • サブコマンド。例えば $ hanami generate actiongenerate action
  • 拡張性。外部 gem が Hanami にサブコマンドを追加できるようになった。

Hanami じゃなくても使えるので、thor の代替案として考えれば良い。

Top-Level Constant Lookup Removed in Ruby 2.5

同一ネームスペース内で見つからなかった定数をルートネームスペースから探すのが Ruby 2.5 からなくなった。その経緯を語る Redmine チケット。

Monkey Patching in Ruby: A Real World Example

Surrealist gem に対応するように、ArrayActiveRecord::Relation のモンキーパッチを検討した話。 下記条件全部満たせなければ、モンキーパッチやめたほうがいいと。

  • これ以上のモンキーパッチはない。
  • モンキーパッチしたコードに依存しているものが壊れない。
  • モンキーパッチ以外の選択肢がない。
  • 新しいインタフェースが作れない。

Organizing My First Conference: Southeast Ruby

カンファレンスを初めて主催した経験談。地方カンファレンスがなくなってきたのがきっかけ。

  1. 昔あったナッシュビル市の Ruby Hoedown カンファレンス主催者から許可を得た。
  2. ドメイン取得(自腹)。
  3. 会社設立(自腹)。
  4. ロゴ発注(自腹)。
  5. キーノート登壇者を招待した。
  6. CFP を 1.5 ヶ月開催。もうちょっと長くすればよかった。
  7. 予算計算。$199 のチケットを 175 枚売れば黒字。
  8. 会場探し。
  9. スポンサー探し。大変だったため、プランはもうちょっと安くすればよかった。
  10. 登壇者宿泊 + 交通費負担することにした。
  11. チケット発売。SNS + Ruby Flow + Reddit で宣伝。87 枚売れた。
  12. カンファレンス 3 日間開催。

赤字だったが、Ruby コミュニティに貢献できた充実感で、来年も開催予定!

News

Rails 5.2 Adds Options for Signed and Encrypted Cookies

Rails 5.2 では、暗号化・署名付きクッキーの有効期限が設定可能に。

RubyElixirConf Taiwan 2018 Call For Papers Open

台北の RubyElixirConf Taiwan 2018、CFP 開始。

New Book Released, 'Mastering Ruby Strings and Encodings'

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 でメールを受信・パースする手順。

  1. ngrok で手元マシンへの URL を用意。
  2. Mailgun で受信したメールを ngrok URL に転送するように Mailgun を設定。
  3. Griddler gem を Rails アプリにマウント。
  4. EmailProcessor オブジェクトでパース・処理を実装。

HTTP2 Early Hints in Rails 5.2+

Rails 5.2 の HTTP2 Early Hints を発表した Eileen Uchitelle 先生。Rails がレスポンスを 2 つ返すようになる:

  1. Early Hints(HTTP ステータス 103)
  2. 通常のレスポンス(HTTP ステータス 200、404、500 など)

Early Hints はブラウザーが優先的にダウンロードするファイル(JavaScriptCSS など)の指定。Rails での検証手順も記載されてる。

A Look at Ruby 2.5's Improved Stacktraces

Ruby 2.5 スタックトレースの見た目改善。エラー発生行番号が一番下になった。長いスタックトレースの上までスクロールすることがなくなって便利。しかし RailsRSpec では効かない。

Extracting a Class from a Method

巨大メソッドをクラスに抽出した話。

7 Little-Known Ruby Methods To Help You Write Better Code

Ruby のよく知られてないメソッド。

  1. Integer#digits (Ruby 2.4 以降)
  2. #tap
  3. Array#values_at
  4. Hash#transform_values (Ruby 2.4 以降)
  5. Kernel#itself (Ruby 2.2 以降)
  6. Array#count
  7. Enumerable#cycle

Upload Images to S3 in GraphQL Using Rails and Paperclip

PaperclipRails GraphQL API から画像を S3 にアップロードした話。REST アプリならドキュメンテーションはいっぱいあるが、GraphQL アプリは一切ない。画像を Base64 文字列に変換してから mutation の引数として Paperclip に渡した。

PDF Filter Implementation in HexaPDF Using Fibers

HexaPDF gem の PDF ファイル読み込み処理解説。

  • PDF ファイルは不特定多数のストリームで構成されてる
  • 各ストリームには不特定多数のフィルターが指定されてる
  • フィルターはストリームデータの解読方法を定義している(例:JPEG 画像は DCTDecode フィルター、ASCII 文字列は ASCIIHexDecode フィルター)
  • フィルターはそれぞれ HexaPDF::Filter::ASCIIHexDecode のようなモジュールで実装されてる
  • ストリームは HexaPDF::StreamData オブジェクトでカプセル化
  • ストリームのデータは非同期で読み込むため、Ruby の Fiber 採用

A Guide to Understanding the Rails Directory Structure

Rails フォルダー構造まとめ。

Updating Deeply Nested Attributes with RSpec

RSpec で深階層の nested attributes を指定した話。手で組み立てるのが大変だった。先輩に相談したら、ログからコピペすることになった。

Tools

nullalign: Generate Warnings for Missing Not-Null Constraints

NOT NULL 制限のない validates presence: true を検知してくれる nullalign gem。

Code

PgParty: PostgreSQL 10 Partitioning for ActiveRecord

ActiveRecord + PostgreSQL 10 パーティション管理用 gem.

Ruby Weekly #369: 日本語サマリー

職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。

rubyweekly.com

Highlights

Could We Drop Symbols From Ruby?

SymbolString の不一致がバグの根源なので、Ruby から Symbol を捨てないかという提案。

  • 下位互換性を維持するには、Symbol#freeze した String にすれば良い。
  • Symbol#to_s から #freeze されてない String を返すようにする。
  • #hash を同等にする必要がある。Symbol#hash 計算が 2〜3 倍速いから、String#hash 計算も Symbol#hash に合わせたい。

Fixnum Bignum 捨てたし、Symbol も捨てれるのでは?と。

Ruby Dev Summit: A Free Online Event for Rubyists

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。

Rediscovering Modularity in Ruby

株式会社デジカの Chris Salzberg 氏が RubyKaigi でトークを発表した話。たまたま Matz のキーノートと同じく、モジュールを題にしてた。しかし「モジュールはクラスではない」と言わんばかりの Matz 発言が Salzberg 氏のトークと矛盾してたのでちょっと困った。ModuleClass だからこそ Ruby ならではの Module Builder パターンが可能。

'ubygems.rb' Removed from Ruby Core

-rubygems に対応するための ubygems.rb が削除された、というちょっと面白いコミット。

Embracing Functional Programming in Ruby

Gusto 社の給与システムが関数型 Ruby になるようにリファクターした話。

  • PFaaO パターンで純粋関数オブジェクトを実装した。給料計算関数オブジェクトを例として挙げた。
  • 純粋関数オブジェクトなので、メモ化していても参照透過性が維持されてる。
  • 給料計算関数オブジェクトの中の税金計算メソッドを税金計算関数オブジェクトに抽出した。
  • ActiveRecord モデルそれぞれに対して immutable な Value Object を切って、純粋関数オブジェクトにValue Object のほうを渡すようにした。

News

Announcing Hanami V1.1.0.beta3

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 機能など込み。

How to Program Vim Using Ruby

RubyVim プログラミングした話。

  1. Angular プロジェクトの該当 directive ファイルを開く関数

Perusing delegate.rb from Ruby’s Standard Library

Ruby コアの delegate.rb をコードリーディングした話。

  • Delegator が継承しているのは、不要なメソッドを省略された Kernel
  • #initialize #method_missing メソッドは Delegator にて実装されている。
  • デリゲート先オブジェクトの accessor は SimpleDelegator など子クラスで実装されている。
  • #method_missing がチェックするのはデリゲート先オブジェクトと一部省略した Kernel

Accessing Hash Values with Fallbacks for Missing Data

Hash#fetch でデフォ値を返すようにする。ブロック渡せば遅延評価もできる。

One Simple Trick to Make Event Sourcing Click

筆者著作の Domain-Driven Rails 本の抜粋。メソッドを 2 つのメソッドに分解することで Event Sourcing するというルールの解説。2 つのメソッドとは:

  1. イベントを発行するメソッド
  2. イベントの効果を適用するメソッド

Some Interesting Methods and Behavior with Arrays in Ruby

Ruby 配列いろいろ

  • #initialize 方法いろいろ
  • #slice 方法いろいろ
  • #insert 方法いろいろ
  • <=> 挙動
  • | 挙動
  • & 挙動

Ruby 2.4 Has Optimized Enumerable 'min' and 'max' Methods

Ruby 2.4 では Enumerable#min Enumerable#max Enumerable#minmax が速くなった!

Considering Performance and Unique Validations in Rails

validate uniqueness: 使用時の高速化案。

  1. インデックスを張ること。Rails の validation を高速化するため。
  2. UNIQUE インデックスを張ること。Rails の validation を完全に省けるため。

筆者作品の UniqueValidationInspector gem では、インデックスのない validate uniqueness: を検知できる。

Ways to Check Which Ruby Version You're Using

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 スレ。

How A Lifelong Rubyist Made Some Python Code 5x Faster

Python コードのパフォーマンスを最適化した Richard Schneeman 先生。

Ruby との共通ルール:

  • ダブってるロジックを省けば軽くなる。
  • オブジェクトのインスタンス化を省けば軽くなる。
  • オブジェクトのシリアライズを省けば軽くなる。例:シリアライズした配列を引数として渡すよりも、要素を渡したほうが軽い。
  • ループ内のリテラルを省けば軽くなる。リテラル=オブジェクトのインスタンス化なので。
  • 不要なロジックを省けば軽くなる。あり得ない if 文の分岐点など。
  • メソッドを省けば軽くなる。効果はそんなに大きくないので、このルールに関しては無理しなくて良し。
  • ベンチマーク必須。
  • キャッシュするなら、オブジェクトのインスタンス化ルールは破って良し。

What I Learned After Going 18 Months Without Rails

レガシー Rails アプリに呆れて、18 ヶ月も Rails を避けていた経験で得た知見。

Opinion

Don't Use default_scope. Ever. Here's Why.

default_scope ではなく明示的に scope 使おうという主張。

  1. new したモデル属性は default_scope で設定されちゃうのが予期せぬバグの元。
  2. default_scope を外すことは辛い。 unscoped だとアソシエーションのスコープまで外れちゃったりするから。

Tools

Recommended Ruby and Rails Books for Experienced Developers

Ruby 上級者向け書籍。

  1. オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方
  2. Rubyのしくみ -Ruby Under a Microscope-
  3. Effective Ruby
  4. Ruby Way 第2版 (Professional Ruby Series)
  5. Mastering Ruby Closures: A Guide to Blocks, Procs, and Lambdas
  6. Rails, Angular, Postgres, and Bootstrap: Powerful, Effective, Efficient, Full-Stack Web Development
  7. 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。

Virtualearth: Bing Maps API Wrapper

Bing Maps API クライアント用 gem。

Ruby Weekly #368: 日本語サマリー

職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なあらすじを書くようにしています。そのあらすじをここでまとまさせていただきます。くだけた日本語で失礼いたします。

rubyweekly.com

Highlights

Visualizing Your Ruby Heap

Aaron Patterson 先生が Ruby ヒープを可視化した話。ObjectSpace でヒープを JSON で取得し、ChunkyPNGPNG 画像に落とした。

Ruby 2.5's Object#yield_self Method

Ruby 2.5 の Object#yield_self 登場。Elixir の |> 演算子相当。筆者見解では、コードのフロー的には読みやすくなるが、ボイラープレートが多い。

A Gaijin Guide to RubyKaigi

@schneems 先生の外国人として RubyKaigi に参加する豆知識。

  • 内容はテクニカルもの重視。スライドはコード大量。
  • 日本語トークはイヤホンで同時通訳あり。
  • トーク後の質疑応答は、司会が頑張って通訳。
  • 英語トークよりも日本語トーク聞いたほうがいい。あとからアップロードされる動画には字幕・吹替がないから。
  • 英語圏のいわゆる hallway track (参加者同士の交流)は基本ない。日本人は真っ赤の他人に話しかけたり質問したりするのに抵抗があるから。
  • 日本のレストランが狭くて大人数で食事するのが難しい。10 人座れるのは居酒屋ぐらい。そして居酒屋はあまり美味くない。
  • 食事の相手は日本語が喋れる人がいれば非常に助かる。美味い店は英語のできない店が多いから。
  • Yelp はあるが、tabelog 使いましょう。
  • コンビニ飯は意外と美味い。

日本人参加者へのお願い:外国人参加者に積極的に話しかけてください!

Debugging Why Your Specs Have Slowed Down

Thoughtbot 社員がテスト高速化のためにデバッグした話。

  • spec_helper.rb 部分的コメントアウトで下記犯人が判明:
    • 全テスト用の config.before(:each) に feature テストのセットアップが入ってた。type: :feature などのメタタグで用途別に分けた。
    • 全テスト DatabaseCleaner.strategy = :truncation になってた。メタタグで :truncation :transaction 適用した。
  • FactoryGirl 部分的コメントアウトafter(:create) のレコード大量作成が判明。trait に移し、再発防止として ActiveSupport Instrumentation でレコード作成数を見える化した。

OptCarrot: An Excellent CPU Benchmark for Ruby 3x3?

Ruby 3x3 ベンチマークとして作られた NES エミュレーター OptCarrot の紹介。

Using Python's scikit-learn Machine Learning Library via PyCall

PyCall gem 経由で Pythonscikit-learn 機械学習ライブラリーを Ruby から呼ぶ手順。

News

Rails 4.2.10 Released

サポート終了済みの Rails 4.2 は、デグレ対応のため 4.2.10 リリース。

Forking Behavior Changed in macOS 10.13, Causing Failures

macOS High Sierra の fork 挙動が変わったため、Puma ワーカーが失敗する現象発覚。

未解消!

Tutorial

Strange Hash Instances in Ruby

#eql? #hash のモンキーパッチで

  • 異なるキーで同一値のハッシュ
  • 同一キーで異なる値のハッシュ
  • 時間限定キーのハッシュ

インスタンス化した話。FixnumStringSymbol は C レベルで塞がれているが、それ以外のオブジェクトはモンキーパッチできた。

良い子は真似しないでね。

Object#try Considered Harmful

Object#try が有害だという主張。オブジェクトがヌルな場合でも、メソッドが定義されていない場合でも、エラー投げずにヌルを返し、正当なエラーまで隠滅してしまうから。

代替案:

  • ヌルチェックを明示的な if 文で。
  • デメテル法則厳守。
  • DB レベル NOT NULL でヌルを防ぐ。
  • 暗黙の to_s などに頼らず、明示的に該当データ型に変換。
  • ダックタイピング。
  • ヌルオブジェクトパターン。
  • &. は OK。ヌル以外のオブジェクトでメソッドが定義されていない場合は NoMethodError を投げるから。

Running Background Workers with Crontab

crontab + whenever gem で Sidekiq ジョブを定期的に起動する手順。

How to Implement a GraphQL API in Rails

graphql gem で Rails アプリの GraphQL API を実装した話。

  • Query でデータ取得用 API 定義
  • Mutation で破壊的 API 定義(例としては JWT 認証 API

How To GraphQL チュートリアルも参考に。

How to Build a React App that Works with a Rails 5.1 API

Rails 5.1 で React のアイデア付箋 CRUD アプリの実装手順。

  1. Rails API 実装。
  2. Facebook 社の Create React App で新規 React アプリ生成。
  3. IdeasContainer IdeaForm などコンポーネント実装。
  4. NPM の axios ライブラリで API を叩く。
  5. rack-cors gem で CORS 制限解消。
  6. NPM の immutability-helper ライブラリで React 上データのイミュタブル性を保証しながら更新。
  7. React Developer Tools ブラウザー拡張で状態監視。

All The Ways to Generate Routing Paths in Rails

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 文字列ハードコード

Building Something Besides a Chat App with ActionCable

PDF 非同期生成の生成完了通知を ActionCable で実装した話。Michael Hartl 先生の Learn Enough Action Cable to Be Dangerous を参考にしていた。

Get Into (Very Basic) Sentiment Analysis with Ruby

Ruby 感情分析ツールまとめ。

Ruby Weekly #367: 日本語サマリー

職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。

rubyweekly.com

Highlights

Awesome Ruby: Curated List of Ruby Libraries and Tools

Ruby ツールまとめ。

How Mutation Testing Causes Deeper Thinking About Your Code

mutant gem のミュテーションテストでモジュールの設計を見直した話。mutant が @unpublished_events = []@unpublished_events = nil に変えたのに、テストがそのまま通った。原因は getter がメモ化していたから。getter が必要なののは、#initialize で設定していないから。#initialize を prepend してみたが、無理矢理すぎて結局何も変えないことにした。

Crystal: The Ruby You’ve Never Heard of

Crystal はシンタックスRuby に非常に似ていてかつ速い。筆者のスクリプトも Crystal が 80 倍速かった。

Crystal の特徴:

  • Type Union: 1 つの変数で複数データ型を許容できる
  • Type Inference & Checking: コンパイル時にデータ型チェック・推論
  • Concurrency: Fiber に対応しているが、マルチスレッドはこれから
  • マクロでメタプロ
  • Ruby からも呼べる

Machine Learning Basics: K Nearest Neighbors

Google 社員の Aja Hammerly 先生がアヤメのデータセットで k 近傍法を紹介。アヤメのデータセットを散布図でプロット。品種の不明なアヤメの花もプロットしたら、図上距離の最も近いものが同一品種だと推測できる。図上距離はピタゴラスの定理で計算。

News

Ruby Together's August 2017 Update

  • Steve Klabnik 先生が Ruby Together 委員会から引退。Rust に集中するため。
  • Bundler が Ruby コアに同梱。

Tutorial

Don't Call Us, We'll Call You: Sending Webhooks with Rails

Rails で Webhook を実装する手順。

  • 送信先 URL と該当イベントのマッピングを保存する Webhook::Endpoint モデルと webhook_endpoints テーブル。
  • イベントとペイロードデートをラッピングする Webhook::Event モデル。
  • 各モデルに include する Webhook::Delivery モジュール。モデルのコールバックで Webhook::Delivery#deliver_webhook を呼ぶ。
  • 非同期送信用 Webhook::DeliveryWorkerWebhook::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 として携帯に送信。

Use TTY::Command to Run External Processes in Ruby

TTY::Command gem でシェルコマンドを細かく制御。system... だけでは、下記よくあるニーズが満たせない。

  • exit ステータスが 0 以外の場合は例外を投げる
  • stdout、stderr 抑えて、文字列に格納して返して欲しい

Open3#popen3 なら細かく操作できるが、低レベルで使いづらくてミスりやすい。

Cross-Site Scripting in Rails

Rails のよくある XSS 落とし穴:

  • HTML エスケープを止める rawhtml_safe や ERB の <%== %>
  • HTML 属性の " 漏れ。
  • link_to の URL。
  • テンプレート内 JSONRailsjson_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 以前はシステムタイムゾーンに変更していた。

Composable RSpec Matchers

カスタム matcher BeEventRSpec::Matchers::Composableinclude することで

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 を実現した話。

Watch Out for This Ruby Blocks Scope Gotcha

metrics_tracker ローカル変数の定義までトランザクションのブロックに囲ってしまったら、ブロック外で metrics_tracker の呼び出しでバグを起こした話。

Using Rails' MessageVerifier for Stateless Token Management

メールで送るパスワードリセット用リンクなどのトークンを生成・検証してくれる ActiveSupport::MessageVerifier の実用例。トークンは DB に保存しないためセキュリティ抜群。

Tools

ezpaas-cli: A Miniature Docker-Powered Heroku Clone for In-House Deployments

Heroku の OSS クローン。動的インスタンスは Docker で。

py2rb: An AST-Based Python to Ruby Code Translator

PythonRuby 変換用 Python スクリプト

Code

Roda 3.0 Released: A Routing Tree Web Toolkit

Sequel ORM 生みの親 Jeremy Evans 先生の routes 用 gem Roda 3.0 がリリースされた。

Searchkick: Intelligent Search for Rails Apps

機械学習 + Elasticsearch 検索機能用 Rails engine。クエリ正規化など対応。

Ruby Weekly #363: 日本語サマリー

職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。

rubyweekly.com

Highlights

An Introduction to Concurrency Models in Ruby

Ruby 並行処理まとめ

  • プロセス。多数コア使えるが、fork が重い。
  • スレッド。プロセスより軽量だが、管理が複雑。競合状態防止とかの。
  • EventMachine gem。スレッド管理してくれるが、コールバックが複雑。
  • Fiber。EventMachine のコールバックを隠してくれる。
並行処理方式 サーバ例 バックグラウンドジョブ例
プロセス Unicorn Resque
スレッド Puma Sidekiq
EventMachine Goliath AMQP

Five Ruby Methods You Should Be Using

この 5 メソッド活かそうぜ!

  1. Object#tap
  2. Array#bsearch
  3. Enumerable#flat_map
  4. ブロック付き Array.new
  5. <=>

Some Confusing Features in Ruby

Ruby の紛らわしい 6 機能

  1. [] メソッド。Array にも Hash にも String にも Proc・lambda にも付いてて諸悪の根源だと筆者が主張。
  2. % 演算子剰余演算子にもなれば、文字列のフォーマット演算子にもなる。
  3. Integer#zero? メソッド。== 0 のほうが無難。
  4. $数字 グローバル変数
  5. Time.parse。不正な文字列渡しても、不正な部分だけ Time.now で埋め込んじゃうという時限爆弾。
  6. Delegator

Spree 3.3 Released: A Rails-Based E-Commerce System

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

Five Quick Active Record Query Tricks

ActiveRecord トリック 5 点

  1. join の条件は scopemerge しよう
  2. join は普段 INNER JOIN になるんだが、ネストすると LEFT OUTER JOIN になることもあるので要注意
  3. EXISTSNOT EXISTS は便利メソッドで
  4. サブクエリは pluck 悪用せずに ActiveRecord に任せよう
  5. to_sqlexplain 活かそう

News

Passenger 5.1.8 Released: Nginx 1.12.1, Webpacker, and Fixes

Passenger 5.1.8 リリース

  • apt-get パッケージがやっとバージョンアップ(1.10.3 以降はできてなかった)
  • webpacker 対応
  • 冗長なログが見やすく

Tutorial

Factories or Fixtures? Give Me Both

Factory と Fixture の力を合わせて外部 API を擬似化。eBay の巨大 XML レスポンスを例に挙げた。XML の Fixture を Factory に読み込み、Hash に変換。

Managing Threads with Queue and SizedQueue

Ruby コアのスレッド間データ通信クラスまとめ。Queue#push でデータを積むと、別スレッドの Queue#pop でそのデータが取得できる。上限付きキューは SizedQueue で。

Adding Token Based Auth to a Rails API with Devise Token Auth

Devise Token Auth gem で Rails APIトークンベース認証を実装する手順。

A Review of the Hanami Web Framework

Hanami のレビュー。

アーキテクチャ

  • Generator 完備
  • Migration 完備
  • Shotgun gem で code reloading 完備
  • モデル層が Entity と Repository に分かれてる
  • コントローラ層は 1 アクション = 1 クラス
  • ビュー層は Template と View に分かれてる

感想

How to Make AJAX Calls in Rails 5.1

Rails 5.1 で AJAX を使う方法 3 通りとそれぞれの導入手順。

  1. rails-ujs(jQuery なし)
  2. jQuery
  3. axios

The === (Case Equality) Operator in Ruby

=== いろいろ

  • クラス・モジュールを被演算子にした場合は kind_of?
  • 正規表現を被演算子にした場合は =~
  • Range を被演算子にした場合はその範囲内
  • Proc を被演算子にした場合は call
  • それ以外のオブジェクトを被演算子にした場合は ==

Tools

Ruby Tests Profiling Toolbox: Tools to Analyze Test Suite Performance

先週にも紹介された TestProf メトリックス計測ツール群。

Code

sinatra-graphql: A Sinatra and GraphQL Starter Kit

clone、カスタマイズ用の Sinatra + GraphQL 骨組みアプリ。Trailblazer、Apollo、React も込み。

tlsh: Trend Micro Locality Sensitive Hash Library

ファジーマッチング用 gem。類似比較で使えるハッシュ値を生成してくれる。

Marginalia: Attach Comments to ActiveRecord's SQL Queries

ActiveRecord ログの SQL にコントローラやアクションなどのコメントを添える gem。Basecamp 作品。

Zammad: A Web-Based Open Source Customer Support System

OSS カスタマーサポート用 Rails アプリ。

Geocoder: A Complete Ruby Geocoding Solution

ジオコーディング用 gem。住所で経度・緯度を算出し、その逆の照合も可能。

Ruby Weekly #362: 日本語サマリー

職場の Slack の #ruby 窓で Ruby Weekly メルマガが毎週配信されます。その中から面白そうなものをピックアップして、日本語で簡単なサマリーを書くようにしています。そのサマリーをここでまとまさせていただきます。くだけた日本語で失礼いたします。

rubyweekly.com

Highlights

TestProf: A Doctor for Slow Ruby Tests

メトリックス計測ツール群 TestProf でテスト最適化。

  • TagProf で重いテスト特定
  • RubyProf、StackProf と併用して重いスタック特定
  • EventProf で DB 処理の重いテスト特定
  • EventProf で重いバックグラウンドジョブ特定
  • FactoryGirl の不要なデータ作成を FactoryDoctor で特定
  • RSpecStamp で動的に不合格テストにタグを張る

To Join or Not to Join?

N+1 クエリ撲滅方法比較

preload

  • 2 SELECT

eager_load

  • 1 LEFT OUTER JOIN

joins

  • 1 INNER JOIN

includes

  • Rails 4 以前は、魔術で preload eager_load joins の中からベストを選択してくれた
  • Rails 5 以降は、includespreloadreferencesJOIN を強制させる(魔術の保守を諦めたコアチーム)

Teaching An AI to Play A Simple Game Using Q-Learning

Q 学習アルゴリズムRuby で実装して、ゲームの AI を学習させた話。

Using 'synvert' to Rewrite and Refactor Code

synvert gem で

flash[:notice] = "Hoge"
redirect_to root_path

の古い表記をよりなうい

redirect_to root_path, notice: "Hoge"

に書き換えた話。

Sending Massive Emails Considered Harmful

好きな 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

3 New Committers Join The Rails Team

Rails コアチーム新メンバー

Tutorial

Use Batching to Avoid N+1 Queries

N+1 クエリ解消策には eager loading、preloading のほかに バッチング策 もあった。筆者が FacebookHaskellHaxl ライブラリに倣って BatchLoader gem を作った。並列処理、GraphQL を活用例として挙げた。スレッドセーフでキャッシング完備。

That One Time I Used Recursion to Solve A Problem

イベントのチケット販売アプリのリマインダー通知を再起計算でスケジューリングした話。チケット購入直後とイベント開始直前のリマインダーは頻繁に、その間はもっと永い間隔で。

How I Got RSpec to Boot 50 Times Faster

RSpec のブートを 50 倍速くした話。答えは spring。rvm のローカル gemset を最低限に減らしても大差はなかった。

A Guide to Using Polymorphic Associations in Rails

ポリモーフィック関連付けの解説。レストランのレビューとイベントのレビューを表す Review モデルで例を挙げた。

Quick Tip: The Builder Design Pattern in Ruby

Builder デザインパターンRuby で実装。ここであらすじ書かなくても原文のコードは読みやすくて分かりやすい! ★★★

Using Encrypted Secrets on Rails 5.1

Rails 5.1 の暗号化 Secret。

bin/rails secrets:setup で下記ファイル生成:

  1. config/secrets.yml.key(キーファイル。コミットするな!絶対に)
  2. config/secrets.yml.enc(暗号化 Secret ファイル)

bin/rails secrets:edit で修正。

キーファイルをサーバに置く方法:

Story

Evolution of the Heroku CLI: 2008-2017

Heroku CLI の進化。

v1〜v3

v4

  • Go + Node
  • Go だけでは動的ライブラリに対応できなかったので、プラグイン機能は Node で
  • CLI コアまでプラグインに抽出
  • 初回実行で Node + コアプラグインをダウンロード
  • 2 年間じっくりかけた

v5

v6

Tools

Fabrication vs FactoryGirl: Which is Faster?

Fabrication vs FactoryGirl ベンチマーク。ネストしているモデルの場合は、Fabrication のほうが速い。create は特に。

Code

Hanami v1.1.0 Beta 1 Released

新機能

  • belongs_tohas_onehas_many :through アソシエーション
  • thor 捨てて hanami-cli gem 新規作成
  • Entity のマニュアルスキーマ定義(ActiveModel の属性定義に相当)
  • CLI からブートするアプリ指定
  • ログの機密情報マスク(Railsfilter_parameters に相当)

Rack::Attack: Rack Middleware for Blocking and Throttling

DDOS 防止 Rack::Attack gem

Staytus: An Open Source Service Status App

システムステータス告知用 Rails アプリ

bettercap: A Modular, Portable and Extensible MITM Framework

中間者攻撃用 gem。脆弱性検証でも使えるらしい。

ruby-knn: A Simple k-Nearest Neighbors (kNN) Classifier

k 近傍法による分類用 gem(機械学習