Tech Racho エンジニアの「?」を「!」に。
  • 開発

週刊Railsウォッチ(20170721)ActiveStorageは5.2で正式導入、Onigmoの脆弱性が修正、この夏読みたい名作Ruby本ほか

こんにちは、hachi8833です。この季節は水筒を持ち歩かないと命が危ない気がしています。

7月第3週のRailsウォッチ、いってみましょう。

ActiveStorageが正式発表: Rails 5.2から導入(Rails公式ニュースより)

先々週のRailsウォッチで速報でお伝えしたActiveStorageが公式に発表され、5.2から導入されることが決定しました。

ActiveStorageのToDoリスト

  • 全クラスのAPIドキュメント作成
  • ダウンロード内容のストリップとクラスの削除
  • MirrorServiceを変換してスレッド化
  • Marcel経由でmetadataを読み取る?
  • Migratorの追加: サービス間でのコピー/移動用
  • クラウドへのダイレクトアップロードの検討
  • MessageVerifier機能: VerifiedKeyWithExpirationを抽出してRailsに

つっつきボイス: 「ワイ先々週のつっつき会おさぼりでしたが、ActiveStorageって何でしたっけ」「Amazon S3やCarrierWaveなんかのストレージを抽象化する感じですね」「おおなるほど: ストレージの移行にも使える感じ」「うれしい人いっぱいいると思います」
「先々週見たときはActiveStorageにはAPIドキュメントがこれっぽっちもありませんでしたがw」「大変そうだなー」
「ローカルファイルも扱えるのか」「CarrierWaveがローカルファイル扱えるから当然」


今見るとドキュメントが着々と追加されているようです。

Rails 5.1.3rc1と5.0.5rc1がリリース(Rails公式ニュースより)

マイナーアップデートなのでバグ・セキュリティ関連と思われます。

Rails: 今週の改修(Ruby公式ニュースより)

#29742#29699は期せずして先週のウォッチで公式より先回りしていましたので省略します。

新機能: rails secrets:showコマンドを追加

# railties/lib/rails/commands/secrets/secrets_command.rb
+      def show
+        say Rails::Secrets.read
+      end

実行にはkeyファイルが必要です。y-yagiさんのプルリクです。

レビューで「editで更新なかったときにはファイル更新しない方がよいのでは」との指摘があり、#29705で即修正されました。

# railties/lib/rails/secrets.rb
-          write(File.read(tmp_path))
+          updated_contents = File.read(tmp_path)
+
+          write(updated_contents) if updated_contents != contents

つっつきボイス:rails secretsって使ったことなかったナー」「マスターキー以外の秘密情報をリポジトリで管理できるようにするやつですね: アプリの秘密情報が増えてきたらこういうの欲しくなる感じ」「お、secrets:editもある:エライエライ」

新機能: #freeze_timeタイムヘルパーメソッドを追加

# activesupport/lib/active_support/testing/time_helpers.rb
+      def freeze_time(&block)
+        travel_to Time.now, &block
+      end

つっつきボイス: 「タイトルにもあるけどtravel_to Time.nowのエイリアスだそうです」「どこで使うのかなっと: ActiveSupportのtime_helpersだからテスト用か」「テストコードのテストコードがあるとややこしい」

修正: PostgreSQLのUUIDが無効な場合に対応

UUIDで{}の一方が欠けている場合に対応しました。

# activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid.rb
-          ACCEPTABLE_UUID = %r{\A\{?([a-fA-F0-9]{4}-?){8}\}?\z}x
+          ACCEPTABLE_UUID = %r{\A(\{)?([a-fA-F0-9]{4}-?){8}(?(1)\}|)\z}
# activerecord/test/cases/adapters/postgresql/uuid_test.rb
+     "{a0eebc99-bb6d6bb9-bd380a11}",
+     "{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11",
+     "a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}"].each do |invalid_uuid|

つっつきボイス: 「UUID壊れてたらどっちみちPostgreSQL側でエラーになると思うけどねw」「orphanってちょくちょく見かける技術用語」

  • orphan: 孤児

Ruby trunkより

forkしてRandom::DEFAULT.randを呼ぶとSegfault

puts "before fork: #{Random::DEFAULT.rand(42)}"

fork do
  puts "child: #{Random::DEFAULT.rand(42)}"
end

つっつきボイス: 「Segfault後にPryが落ちずに復帰したのがちょっとびっくりでした」「Pryならやるかも」
forkはKernel関数なのか」

関係ありませんが、カタカナで「セグフォ」と書くことに何となく抵抗を感じてしまう私でした。口頭なら気になりませんが。

defined?**を使うと落ちる

defined?(a **{}) # 落ちる

hash_table_index()でヌルポ

0/defined?0--begin
e=m
return
0end

なにこれ怖い。


つっつきボイス: 「ぬわー、#13755は何だこりゃ」「冒頭の0/は割り算?」
「それにしてもissueがおしなべて無言ですね」「コードに語らせるというやつですな」

Ruby: Onigmoの脆弱性を修正

無効なパターンでオーバーフローが発生する脆弱性だったとのことです。
k-takataさんが粛々と修正してくれました。ありがとうございます。

# testpy.py
+    n("[\\6000", "a", err=onigmo.ONIGERR_TOO_BIG_NUMBER)   # CVE-2017-9226
+    n("[\\H- ]", "", err=onigmo.ONIGERR_UNMATCHED_RANGE_SPECIFIER_IN_CHAR_CLASS)  # CVE-2017-9228

今さらですが、OnigmoはRuby 2.0以降で採用されている多機能な正規表現エンジンで、Ruby以外の環境でも採用されています。私が最も頻繁に使っている正規表現エンジンです。
漢字では「鬼雲」と書くそうです。「鬼蜘蛛」じゃなかったのか。


つっつきボイス:[\\6000は閉じ]が落ちてるやつで、[\\H- ]は範囲の-の終端がスペースになってて無効なのか」「正規表現書いているとこういう間違いって簡単に発生しそう」

Ruby on Railsベスト書籍はこれだ: 2017年度版(RubyFlowより)

なおこのブログではベストなんとか記事が他にも並んでいました。


reactdom.comより

  • The Complete Ruby on Rails Developer Course
  • Dissecting Ruby on Rails 5 – Become a Professional Developer
  • Ruby Metaprogramming – Complete Course
  • Ruby on Rails 5 – BDD, RSpec and Capybara
  • 8 Beautiful Ruby on Rails Apps in 30 Days & TDD – Immersive
  • Ruby on Rails Tutorial: Learn Web Development with Rails
  • The Well-Grounded Rubyist
  • Effective Ruby: 48 Specific Ways to Write Better Ruby
  • Eloquent Ruby
  • The Ruby Way: Solutions and Techniques in Ruby Programming

古くからある書籍も改訂されているようです。日本語になってるのとなってないのが半々ぐらいです。


つっつきボイス: 「(右クリ辞書をひきながら)Well-Groundedって『基礎のしっかりした』か」「1冊目は『Developer Course』ってなってる」「講習会受けるともらえる本みたいなやつかな」「最近のRailsチュートリアルはちょっとボリューム多すぎな気がする」「張り切って書きすぎたのかしら」

「ちゃんとした出版社から出ている本はきちんと書かれている点がやっぱりよい」「メジャーな出版社なら校正や編集もみっちりやってるはずですからね」「今は誰でもPDFでさっと本を作れてしまうけど、そういう英語の野良本をいくつか買ってみるとページ数の割に内容が薄かったり細かい間違いが多かったり」

「この夏休みにこの中から一冊ぐらいは選んで読んでみるといいと思われ」「お盆休み潰せばできるできるw」


今さらですが、技術書の英語はたいていの場合新聞や小説よりもずっと楽に読めます。ものにもよりますが、用語がしっかり定められていることが多く、代名詞の利用が控えめなので何を指すかで迷いにくく、小洒落た言い回しや邪魔っけなアメリカンジョークもそれほど多くなかったりするので。

JetBrainsが調べたRuby開発者の環境


www.jetbrains.comより

morimorihogeさんがSlackに投下してくれた記事です。JetBrainsカラーで統一されたグラフィックがきれいで楽しく読めます。


つっつきボイス: 「JetBrainsのアンケートベースだから、全Ruby開発者の状況とはまた違うと思われ」「others: 1%ってこれRuby 1.8以下ってことだよね: コワイコワイ」
「rvenvがRVMをちょっと上回っている」「Rails 3はだいぶ少なくなってきたか」
「生Rackでアプリ書く人ってけっこういる?」「RailsもHanamiもSinatraもみんなRackに乗ってますけどねw」
「Pumaずいぶん増えた: しかもproductionで」「Railsのデフォルトサーバーになったからでしょうね」「ちなみにBPSの標準はUnicorn」

その場でmorimorihogeさんがアンケート: お楽しみ編も見つけてくれました。


www.jetbrains.comより

Rubyのゲーム好き(65%)はフルタイムC#開発者(73%)より少し少ないようです。


つっつきボイス: 「シューティングがないわい」「Actionに入ってそう」「自分、パズル系ゲームぐらいしかやってない...」「これだとOthersかな」
全然寝てない人がいる!」「それはアカンやつや」

Railsの監査/バージョニングgem対決: AuditedかはたまたPaper Trailか?(RubyFlowより)

結論はというと、「目的による」という無難なところに落とし込んでいます。
Auditedは「Active Record User Stamping」で主に特定ユーザー追いかけ用、Paper Trailは「Active Record Versioning Area」で主に関数やメソッドなどの領域ベースで時間軸に沿った変更を追うときに、と使い分ける感じです。

なお、paper trailという語は一般には「(証拠物件として文書化された)個人の行動履歴」を指します。

Rails 5 でAPIバージョニングが必要な理由


paweljw.github.ioより

APIのバージョニングに関する記事です。タイトルにあるVue.jsはここでは直接関係なさそうです。

module Api
  module V1
    class AuthorsController < ApplicationController
      # ...
    end
  end
end
module Api
  module V2
    class AuthorsController < ApplicationController
      # 互換性のない変更を行う
    end
  end
end

つっつきボイス: 「APIをどうやってバージョンアップするかは悩む点」「URLを変える方法や、バージョン番号をヘッダとかで示す方法とか」「はっきり覚えてないけど、GoogleはURLを変える方針だった気がする」

RubyMine 2017.2リリース(RubyFlowより)


www.jetbrains.comより

  • Docker ComposeでDockerをサポート
  • Docker Compose内でのデバッグ
  • Rubocopサポートの改良と修正
  • モジュールやクラス名などのパンくずリスト
  • JavaScript/TypeScriptのリファクタリング強化
  • メソッドやフィールド順の自動並べ替え
  • Sass/Scssオートコンプリートの強化


www.jetbrains.comより

つっつきボイス: 「今回の新機能の中ではRubocopのQuick-fix↑がいいな」
「パンくずリストってどこどこ?」「一番下にあるこれ↓」

Carrierwave::AttachmentScanner: CarrierWaveへのアップロード時にウィルススキャンするgem(RubyFlowより)


www.attachmentscanner.comより

★こそ少ないのですが、これはAttachmentScannerというサービスの公式のgemであるとのことです。


つっつきボイス: 「CarrierWaveとは別にこういうサービスを立ち上げたのか: 目のつけどころがいいなー」「どんなウィルススキャンソフトでチェックするんだろう?」

ActiveRecordからXLSXなどを生成するgem 2つ(RubyFlowより)

★の数はどちらも400個台、spreadsheet_architect gemの方が新し目です。


つっつきボイス: 「axlsx_railsはだいぶ前からあって何度か使ったことあるけど、思ったよりずっとよくできていた: けっこう優秀」「spreadsheet_architectはかなり新しいですね」

Railsコードのaudit:アプリレビューの8つのステップ(Random Rubyより)

blog.planetargon.comより

コードレビューサービスを行っているPlanet Argon社のブログ記事です。

  • .ruby-versionファイルはリポジトリにあるか
  • Gemfile.lockはリポジトリにあるか
  • bundle-auditでどんな警告が表示されるか
  • 自動化テストが最後に走ったのはいつか
  • リポジトリに秘密キーなどが登録されてないか
  • ローカルデータベースのseedデータはあるか
  • データベースはインデックス化されているか
  • TODOはどのぐらい残っているか

つっつきボイス: 「うん、おおむね同意」「Gemfile.lockないとかヤバイ」「他社からの引き継ぎ案件をざっとチェックしていて、seedデータも用意されてなかったりすると、ああここはアカンなと思ったりしますね」

参考: ちょっと待った! Railsでgitリポジトリから除外すべきでないファイル:Gemfile.lockとdb/schema.rb

補足: Random Rubyニュース

なおこちらのニュースはRandom Rubyからのものでした。クローラー任せではなく、人間がピックアップしているそうです。今後巡回先に加えようと思います。


newsletter.frey.suより

Turbolinksのライフサイクルを解明する(Random Rubyより)


sevos.ioより

Turbolinksの挙動を深掘りしています。手書きの図がいい味出してます。

# DOMへの副作用を抑えるスニペット例: sevos.ioより
document.addEventListener('turbolinks:load', this.setup(), {once: true})
document.addEventListener('turbolinks:render', this.setup())
document.addEventListener('turbolinks:before-render', this.teardown())

つっつきボイス: 「TurbolinksはRails 5.0になってから随分改善されたと思う」「JavaScriptやjQueryコードを足し始めるとこういうところを追うことになったりしますけど」「ワイは今の案件でいつTurbolinks切ろうか考え中」

Railsの散らかったビューをView Objectで何とかする方法(RubyFlowより)


www.nopio.comより

# www.nopio.comより
class OrderDecorator < Draper::Decorator
  ...

  def ordered_items_amount
    object.items.map(&:amount_ordered).sum
  end

  def discount_percent
    "#{(object.discount * 100).round(2)} %"
  end
end

つっつきボイス: 「普通にdecoratorとpresenterの話かな」「それほど新しくはないけどまとまりよさそう」

参考: 肥大化したActiveRecordモデルをリファクタリングする7つの方法(翻訳)

オピニオン: 欲しいのはもっともっと優れた言語だ

「欲しいのはアプリじゃない、さらに洗練された言語だ」


つっつきボイス: 「でたーバベルの塔w」

ベンチマークの理解の仕方と直し方(RubyFlowより)


blog.phusion.nlより

PassengerでおなじみのPhusion社のブログです。みっちり書かれた良記事です。


つっつきボイス: 「ベンチマークやるならこのあたりの常識は押さえとくべき: 専用ハードウェアでベンチ取るとか」「AWS EC2やHetznerなんかの専用ハードウェアサービスのメリット・デメリットを記事でも比較している」「クラウドでのベンチマークはクラウドのパフォーマンスが変動するから基本あてにならない

「"time budget" ってここではどういう意味なんだろう?」「"Having too few iterations means that the benchmark may produce unreliable results": つまり1回や2回のベンチマークでは信頼できる結果を取れないので、繰り返し回数を十分確保するという感じ」

「"CPU affinity"は?」「"ensure that a process/thread "sticks" to a certain CPU core"、つまりプロセスやスレッドがCPUコア間をなるべく移動しないようにすることですね」


参考: Wikipedia-ja: プロセッサ親和性

ActiveModelの一意性バリデーション

Jean Mertz氏の同名記事「uniqueness validations in ActiveModel」のコードについて、Rails 5.1.2では挙動が少し変わっているとして別解を示しています。

def initialize(options)
  super
  @klass = options[:model] if options[:model]
end

Langsec構想: 言語レベルでインターネットセキュリティ向上を目指す

C/C++に死を」という記事から2ホップほどたどって見つけました。

Go言語でstraceしてみた

Goよりもシステムコールの話が中心です。


つっつきボイス:straceってシステムコールをトレースできるのかー!いいのかそんなことしてw」「できないと困るww: straceはパフォーマンスチューニングのときに一番よく使う」

go-pry: GoでPryやってやったぜドヤァ


github.com/d4l3k/go-pryより

静的言語であるGoでなぜにPryライクなREPLを実装...しかも「メタプログラミングとリフレクションをたっぷり含んでおります」とか、わけわかりません。さすがにまだ不安定な様子。


github.com/d4l3k/go-pryより

作者のd4l3k氏はカナダ在住のようですが、他にもWebSyncでGoogleドライブ+GoogleドキュメントをRubyとReactで再現してしまうとか、プロフィール写真の目つきも含めて何というか一種の狂気のようなものを感じてしまいました。


つっつきボイス: 「技術的には可能ですけどね」「Gopherくんの目の周りの病的な隈がw」「シャブ食ってるみたい...」

どうして動くのかよくわからない1行JavaScriptを読み解く(RubyFlowより)

<pre id=p><script>n=setInterval("for(n+=7,i=k,P='p.\\n';i-=1/k;P+=P[i%2?(i%2*j-j+n/k^j)&1:2])j=k/i;p.innerHTML=P",k=64)</script>

上を実行すると以下になるそうです。


www.alexkras.comより


つっつきボイス: 「こういうパズルみたいなの、ハック系のコンテンストなんかでよく出てくるw」「C++系のコンテンストなんかで、1行のコードで一番長いエラーメッセージを吐かせた人の勝ち、みたいなのもありますw」「そういうのもコードゴルフの一種なんでしょうかwドライバーの飛距離を競うみたいな」

人間中心の機械学習 - Google Design


medium.com/google-designより

つっつき会の後で知りました。エモそうなタイトルとはうらはらに、機械学習に過度な期待をせず、UIデザインに機械学習を応用するときの考え方や手法を具体的に解説している良記事です。

[番外1] dnSpy: .NETアセンブリエディタ/デコンパイラ/デバッガ


https://github.com/0xd4d/dnSpyより

C#向けツールですが、BPS CTOのbabaさんがSlackで「このツール凄い!」と喜びの声を上げていたのでググってみました。ネット上でも喜びの声が続々見つかります。


つっつきボイス: 「おおー、これ確かに凄いww: .NETのバイナリを動的に書き換えたりいろいろやんちゃできるのか」「.NETのバイナリはソースの情報をだいぶ含んでいるからデコンパイルとか割りとやりやすいんだろうな」「難読化ぇ」

参考: 凄すぎて大草原不可避な.NET デコンパイラdnSpyを使ってみる

[番外2] ロボット牧師がドイツに出現


www.theguardian.comより

今どきありえなさそうなロボロボしいデザインは、信者を不安にさせないための気遣いなんですよねきっと。

参考: Wikipedia-ja: ロボット三等兵


今週は以上です。

バックナンバー(2017年度)

今週の主なニュースソース

ソースの表記されていない項目は独自ルート(TwitterやRSSなど)です。

Rails公式ニュース

Random Ruby

RubyFlow

160928_1638_XvIP4h


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。