週刊Railsウォッチ(20171013)Ruby 2.5.0-preview1リリース、RubyGems 2.6.14でセキュリティバグ修正、Bootstrap 4.0がついにBetaほか

こんにちは、hachi8833です。

Rails: 今週の改修

新機能: HTTP/2プッシュ用のEarly Hintsを実装


#30744より

Aaron Patterson氏のロングインタビュー↓でも言及されていた「アーリーレスポンス」がHTTP 103 Early Hintsとして実装されました。

[インタビュー] Aaron Patterson(後編): Rack 2、HTTP/2、セキュリティ、WebAssembly、後進へのアドバイス(翻訳)

とにかく、Kazuhoは新しい標準化を提案することを思いつきました。それは新しいレスポンスコードで、私はそれが101か110だと思っています。これはアーリーレスポンスと呼ばれるもので、HTTP/1の普通のレスポンスコードなのですが、本質的にプッシュ(HTTP/2プッシュ)と同じものです。使っているプロキシがこのレスポンスコードを理解し、それをHTTP/2プッシュに変換するというわけです。
この方法の良い点は、HTTP/1で動くサーバーがあり、そのサーバーの通信相手であるプロキシがHTTP/2で話せるなら、プッシュを行いたいということをプロキシが理解できるという点です。本質的にHTTP/1とHTTP/2のいいとこ取りができるので、HTTP/1サーバーにまったく影響を与えずに引き続きプッシュを行えます。


つっつきボイス: 「上のロングインタビュー時点では@kazuhoさんから提案中だったのが、Aaronさんの期待どおり見事採用されてる」「HTTP/2 Early HintsはRailsに限らない話で、プロトコルが拡張されたことの方が大きい」「ほほー、レスポンスコードは?」「103番ですね」
「Early Hintsについてはこちらのブログ↓見ればひととおりわかります。Web開発者必読

「しかし103番とは随分と若い番号」「HTTP 1xx番台はInformationalなのか: ところでこのWikipediaにはまだ103は書き足されてないから更新必要ですね」
「変更は意外にシンプルだった↓」「環境変数で指定できる: デフォルトはnilだそうです」

# actionpack/lib/action_dispatch/http/request.rb
+    def send_early_hints(links)
+      return unless env["rack.early_hints"]
+
+      env["rack.early_hints"].call(links)
+    end

存在しないAction Cableサブスクリプションの解除メッセージをわかりやすくした

actioncable/lib/action_cable/connection/subscriptions.rb
      def remove(data)
         logger.info "Unsubscribing from channel: #{data['identifier']}"
-        remove_subscription subscriptions[data["identifier"]]
+        remove_subscription find(data)
        end

つっつきボイス: 「これは普通にリファクタリングですね」

テストでRuby 2.5の未使用変数warningが出たのを修正

# railties/test/generators/argv_scrubber_test.rb
-        message = nil
         scrubber = Class.new(ARGVScrubber) {
-          define_method(:puts) { |msg| message = msg }
+          define_method(:puts) { |msg| }
         }.new ["new", "--rc=#{file.path}"]
         args = scrubber.prepare!
         assert_equal ["--hello", "--world"], args

文言修正系PR

# activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
-          raise(ArgumentError, "Postgres requires advisory lock ids to be a signed 64 bit integer")
+          raise(ArgumentError, "PostgreSQL requires advisory lock ids to be a signed 64 bit integer")
-    #  NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
-    #  objects that have already been created, e.g. any model timestamp
-    #  attributes that have been read before the block will remain in
-    #  the application's default timezone.
+    # NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
+    # objects that have already been created, e.g. any model timestamp
+    # attributes that have been read before the block will remain in
+    # the application's default timezone.

つっつきボイス: 「修正と関係ありませんが、英語圏の人ってPostgresって書くの好きですね: 私は翻訳のときは常にPostgreSQLと書き直してます」「日本語のポスグレは口頭でしか使わない感じですね」

compatibility.rbのリファクタリング(DRY化)

コミットメッセージどおり、重複したコードをprivateにまとめています。

# activerecord/lib/active_record/migration/compatibility.rb
          if block_given?
-            super(table_name, options) do |t|
-              class << t
-                prepend TableDefinition
-              end
-              yield t
+            super do |t|
+              yield compatible_table_definition(t)
             end
            else
...
        private
+          def compatible_table_definition(t)
+            class << t
+              prepend TableDefinition
+            end
+            t
+          end

Rails

Rails 5とGriddlerとMailgunでメールを受信してパースする(RubyFlowより)


hackernoon.comより


つっつきボイス: 「ほほー、自前のメールサーバーを使わずにRailsでメール受信トリガの処理を実行する方法か: 普通メール受信をトリガにして何かするときは、postfixとか使って.forwardあたりでスクリプトに受信メールを流し込んで実行したりするけど」

  • Griddler — Railsでメール受信するgem
  • Mailgun — 開発者向けのAPIベースのメールサービス

「なおAWSを使っていいのであれば、SES(Simple Email Service)S3に受信できるので、S3のfile createのイベントをLambdaに流して同じことができるはず」


そこからNAT越え(NAT traversal)の話題になりました。

ngrokというサービスとプログラムを使うと、双方ともNATの裏にいてもtunnelingできるらしい」「ご家庭でゲームのためにUPnPのNAT越え頑張ったりしますね」「UDPホールパンチングなんてのも」「ゲームやらない人なのでこのあたり知らないことだらけ」

shioyamaさんのMobility gem記事

以前のウォッチでもご紹介したRails多言語化gemです。Module Builderパターンの実例についてここでも熱心に解説されています。
この方の英文は(内容の難しさと量は別にしても)とても読みやすいと思います。

RubyのModule Builderパターン #1 モジュールはどのように使われてきたか(翻訳)

Skinny: Scalaで書かれたRails的フレームワーク


github.com/skinny-framework/skinny-frameworkより

ちょっと珍しいので拾ってみました。★も600越えと意外に伸びています。


つっつきボイス: 「これ見てて思ったけど、Railsの方法論はいろんなフレームワークに広がりましたね」
「Railsが流行ってから他のWebアプリケーションフレームワークも軒並みCLIのscaffold的なgeneratorとかを搭載するようになったし、つくづくRailsの影響は大きかったと思う」「以前PHPフレームワークのSymfony使ってたけど、v2はもうホントRailsっぽいCLI」


symfony.comより

Ruby

Ruby 2.5.0-preview1がリリース(Ruby公式ニュースより)

新機能

  • バックトレースを逆順で見やすく表示
  • トップレベルの定数探索を廃止
  • do/endブロック内でrescue/else/ensureを使えるようになった
  • yield_self

その他2.4以降の変更

  • Onigmoの非包含演算子(absence operator)
  • Bundlerが標準ライブラリの仲間入り
  • rubygemsが2.6.13に
  • rdocが6.0.0.beta2に、従来のIRB lexerに代えてRipperを導入し高速化
  • Unicode 10.0.0をサポート


つっつきボイス: 「Ruby 2.5はbundlerがbundleされた点がとてもうれしいので、ぜひ早く安定版が出て欲しい」

RubyGems 2.6.14でセキュリティバグ修正

Aaron Pattersonさんが書いています。RubyGems 2.6.14にアップデートするには以下を実行します。

gem update --system

良いRubyコードを書くためのあまり知られていない7つの技(RubyFlowより)

良記事です。つっつきも大いに盛り上がりました。このRubyGuidesというサイトの他の記事もよさそうです。


つっつきボイス:

  • Integer#digits「桁をバラして配列で取り出せるのかー: 使いみち思いつかないけど」「数学パズルとかに使えるかな?」
  • #tap「このメソッドは、使う人はすごく使うけど使わない人は全然使わないですね: こんなふうに1回だけ#tapするのは気持ちわかる」
User.new.tap { |user| user.name = "John" }

「でもこのサンプルコードみたいにチェインするのは好きじゃない」「う、読みづらい…」

"hello".bytes.to_a.tap {|arr| p arr }
  .collect {|byte| byte.to_s(16) }.tap {|arr| p arr }
#=> [104, 101, 108, 108, 111]
#=> ["68", "65", "6c", "6c", "6f"]
  • #values_at「Arrayの何番目と何番目と指定していっぺんに取り出せるんですね」「これ、Hash#values_atの方が便利そう↓」「paramsのこれとこれだけ取り出したりできるのか」
h = {1=>"a", 2=>"b", 3=>"c"}
p h.values_at(1,3,4)               #=> ["a", "c", nil]
# [h[1], h[3] ,h[4]] と同じ
h = { a: 1, b: 2, c: 3 }
h.transform_values {|v| v * v + 1 }  #=> { a: 2, b: 5, c: 10 }
h.transform_values(&:to_s)           #=> { a: "1", b: "2", c: "3" }
h.transform_values.with_index {|v, i| "#{v}.#{i}" }
                                     #=> { a: "1.0", b: "2.1", c: "3.2" }
  • Kernel#itself「自分自身にアクセスしたいことってたまにある」「これは考えて使わないとよく分からなくなりそう」
string = 'my string' # => "my string"
string.itself.object_id == string.object_id # => true
  • Enumerable#cycle「テストデータを無限に生成するのとかに使えるかも」
a = ["a", "b", "c"]
a.cycle {|x| puts x }  # print, a, b, c, a, b, c,.. forever.
a.cycle(2) {|x| puts x }  # print, a, b, c, a, b, c.

「あー良い記事でござった」「little-knownダナ確かに」

RubyのGILを理解する


dev.to/enetherより

GILといえば卜部さんのブログにこんなことが書いてありました。

GVL (じーぶいえる) GILとも。Global VM Lock。嫌われもの。だがパフォーマンスを犠牲にしつつもみんなを[BUG]から守ってくれてるんだぞ。もっと感謝すべきだ。
‘10年代のRubyコア用語集より


つっつきボイス: 「よく話題になるやつです: ↑ホントこのとおり」「GってGiantのGだったりもしますね」「まあ意味は変わりませんが」「せっかくスレッドがCPUに分割されてもGILが発生すると一斉に一時停止しちゃう」

RubyのSymbolってなくせないの?


つっつきボイス: 「RubyのSymbolって私好きなので、問題だと思ってませんでした」「frozen_string_literalがある今となっては、もしかするとSymbolっていらないのかも」

「Symbolを持つ言語はLispやSmalltalkなど他にもあるけど、おそらくRubyのSymbolって当初の概念からかなり踏み出して独自路線になっちゃったのかも: Symbol#to_sできちゃうとか」「確かに: Symbolをputsするにはto_sが必要だけど、それが当初の想定を超えて文字列代わりにどんどん使われたり」「RailsのHashWithIndifferentAccessなんてのができたり」
「JavaにはSymbolないので、キーの文字列がたまに一意にならなくて数値に変えたりとつらかったなー」

Ruby Rogueポッドキャスト: Martin FowlerとRubyコードをリファクタリングしよう


devchat.tv/ruby-roguesより

Ruby Rogueはこの間のウォッチでも軽くご紹介しました。
Martin Fowler氏はRefactoring — Ruby Editionの著者です。この本の日本語版があったのに今は絶版なのが何とも残念。


つっつきボイス: 「お、目次もあるし、内容もいい感じ」「このポッドキャストは月一ぐらい?」「もっと頻繁みたいです」「それは凄い: 長く続いてるのは大事」
「そういえば日本語だとrebuild.fmという音声ポッドキャストが随分長くやってますね」「rebuild.fmは毎回いろんなベテランエンジニアの話が聴けるのがよくて、BPS社内にも愛聴者がいたと思う」


rebuild.fmより

「Ruby Rogueも同じ感じでやってるようです: DHHインタビューとか、かと思うと元ストリートパフォーマーからRails開発者に転身した人の話とか、盛りだくさんですね」「字幕があれば英語ヒアリング練習にもいいかも」

bolt: SSHやWinRM経由で多数のコマンドを実行するgem(GitHub Trendingより)

$ bolt command run 'ssh -V' --nodes neptune,mars
neptune:

OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013

mars:

OpenSSH_6.6.1p1, OpenSSL 1.0.1e-fips 11 Feb 2013

Ran on 2 nodes in 0.27 seconds

つっつきボイス: 「capあれば同じことできますね」「capって何でしたっけ」「capistranoのコマンド」「あ、そうだった」
「この種のツールはやっぱりsingle binaryで動いてくれる方がうれしいので、自分は使わないかな: Go言語とかで作られてる方が便利だなあ」「perlのスクリプトとか、環境が変わると微妙なバージョン違いで動かなかったりしますね」

  • capistrano — Rubyで書かれたデプロイ/サーバー操作ツール


capistranorb.comより

Rubyはどうやって開発を進めているか


つっつきボイス:伽藍とバザールですね: そうとう昔のですが、今日のOSSの歴史を辿るとまず間違いなく参照される文書: これ以外で伽藍という用語を見たことないけど」
「90年代にオープンソースの隆盛を予言したやつですね: 当時騒いだのは開発者より文化人の方が多かったような覚えが」
「伽藍が読めなかった」「がらん、って大聖堂とかの方がわかりやすいかも」「cathedralだからカテドラルか」


そういえば伽藍という言葉を覚えたのは西遊記でした。六丁六甲、五方掲諦、四値功曹、護駕伽藍。

Ruby trunkより

提案: ファイルが存在する場合にxモードで開いたらraiseすべき->#11258と重複

# C言語: file.txtを作成するが、既に存在していたらraiseする
open('file.txt', 'wx') {|f| f.puts("Some text") }

つっつきボイス: 「openのxモードとか知らなかったー」「wxって最初意味分からなかった」「PHPだけどこんなの見つけた↓」

‘x’ 書き込みのみでオープンします。ファイルポインタをファイルの先頭に置きます。 ファイルが既に存在する場合には fopen() は失敗し、 E_WARNING レベルのエラーを発行します。 ファイルが存在しない場合には新規作成を試みます。 これは open(2) システムコールにおける O_EXCL|O_CREAT フラグの指定と等価です。 このオプションはPHP4.3.2以降でサポートされ、また、 ローカルファイルに対してのみ有効です。
http://php.net/manual/ja/function.fopen.phpより

「manではこう↓」

open(2) システムコールにおける O_EXCL|O_CREAT

「あった、これこれ↓」

O_EXCL
この呼び出しでファイルが作成されることを保証する。このフラグが O_CREAT と 一緒に指定され、 pathname のファイルが既に存在した場合、 open()は失敗する。
https://linuxjm.osdn.jp/html/LDP_man-pages/man2/open.2.htmlより

「他の言語と同じようにPOSIXのopen()に準拠しようよ、ってことか」


そこからPOSIXのシステムコールの名称の話題になりました。

O_EXCLとかO_CREATとかO_TRUNCみたいな、本体が5文字の短いシステムコールは古くからあるやつで、O_NOFOLLOWみたいに長いのはたぶん後から追加されたやつです」「へええ」「昔はこういうところをケチらざるを得なかったんですね」

JavaScript

asyncawaitを4つの例で学ぶ(JavaScript Liveより)

// 同記事より
async function startSynchronous() {
  try {
    const pentaCodeAvatarUrl = await getPentaCodeAvatar();
    const reactAvatarUrl = await getReactAvatar();
    const totalURL = pentaCodeAvatarUrl + reactAvatarUrl;
    console.log(totalURL);
  } catch (e) {
    console.error('Error in startSynchronous (Async Await Based)', e);
  }
}

startSynchronous();

つっつきボイス: 「出たなPromise」「asyncawaitをガンガン使うようなJSコード、納期が超緩い案件ならやってみたい」

amatudaさんのRubyConf Malaysia 2017スライド

CSS/HTML/フロントエンド

Bootstrap 4.0が「ついに」Beta版に


getbootstrap.comより


つっつきボイス: 「公式サイトのトップ画面がついに変わった!」「Bootstrap 4.0で長く待たされた人たちはみんな仏の境地になってますね」「ちょうど今年の学生に『Bootstrap 4.0は当分先です』と教えたところだった」

リモートつっつき: 「Formの書き方が変わり、-xsが廃止になってアイコンフォントも標準付属でなくなったので、3からそのまま入れ替えるとめちゃくちゃに壊れますが、ブレークポイント4段なのがとても良い☺️」
「アイコンフォントの分離は、require(‘boostrap’);時にcssの@importを辿ってWebpackがフォントを読み込もうとして😞 になるのを回避できるので逆に良い」

5分でタイポグラフィを改善するコツ(HackerNewsより)


pierrickcalvez.comより

デザイン寄りの記事です。


つっつきボイス: 「こういうの、日本語の縦書きやルビになると全然違ってきますよねー」「確かに」

Go言語

caddy: Let’s Encryptの証明書を自動で使えるHTTP/2サーバー(GitHub Trendingより)

1か月足らずで驚異の★14,000超えです。


つっつきボイス: 「single binaryで動くので良さそう」「OpenSSLとかもbundleされてるなら嬉しいな」

supervisord: Goで書かれたsupervisor(GitHub Trendingより)

$ supervisord -c supervisor.conf -d

$ supervisord ctl status
$ supervisord ctl stop <worker_name>
$ supervisord ctl start <worker_name>
$ supervisord ctl shutdown

つっつきボイス: 「本家のsupervisord↓と名前が同じでさえなければなー: このままじゃ議論になったときも区別が大変」「コマンドとかconfigは互換保とうとしてるっぽいけど、完全に同じでないと実際に運用しようとするときに問題になりそう」


本家supervisord.orgより

rat: シェルコマンドを組み合わせてターミナルアプリを作るツール(GitHub Trendingより)


github.com/ericfreese/ratより

tig的なCLIツールを作れます。

wow: Go CLI用のかわいいスピナー(GitHub Trendingより)


その他

fd: 改良版findコマンド(GitHub Trendingより)


github.com/sharkdp/fdより

find -iname '*PATTERN*'
fd PATTERN   // 書式がシンプル

Rustで書かれています。カラー表示がうれしいです。

sorting.at: ソートのビジュアル表示


sorting.atより

最初Hacker NewsのSorting Visualizationsにしようかと思いましたがこちらの方がずっと美しくて明快だったので。


つっつきボイス: 「ソートのアルゴリズムを学んでない人にはよさそう」
「ところでソートといえばこの名作動画を思い出しますね↓」「こ、これはw」「なごむー」

cosmos: さまざまな言語で書かれたアルゴリズムとデータ構造コレクション

# https://github.com/OpenGenus/cosmos/blob/master/code/search/binary_search/binary_search.rb より
=begin
    Part of Cosmos by OpenGenus Foundation
=end

def BinarySearch(arr, l, r, x)

    if x.nil?
        return -1
    end

    if r >= l
        mid = (l + r)/2
        if arr[mid] == x
            mid
        elsif arr[mid] > x
            BinarySearch(arr, l, mid-1, x)
        else
            BinarySearch(arr, mid+1, r, x)
        end
    end
end

arr = [3,5,12,56,92,123,156,190,201,222]

number = 12

puts "Position of #{number} is #{BinarySearch(arr, 0, arr.length-1, number)}"

Rubyが少ないのが残念。主催はOpenGenusという団体です。

番外

RoBozzle: 子供も大人も楽しめるパズルゲー


robozzle.comより

Hacker Newsのコメント欄で見つけました。まだ遊んでませんが、ちょっと倉庫番を思い出しました。


つっつきボイス: 「これで思い出したけど、codecombatっていう、ゲームでプログラミングを学ぶサイトも面白いですよ↓: お、今見てみたら前よりずっと進化してる」「ローカライズもかなり頑張ってる感じですね」


codecombat.comより


今週は以上です。

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

週刊Railsウォッチ(20171006)PostgreSQL 10ついにリリース、Capybaraコードを実画面から生成するnezumiほか

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

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

Ruby 公式ニュース

Rails公式ニュース

Awesome Ruby

RubyFlow

160928_1638_XvIP4h

Frontend Weekly

frontendweekly_banner_captured

Hacker News

160928_1654_q6srdR

Github Trending

160928_1701_Q9dJIU

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833

コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。
これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。
かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。
実は最近Go言語が好き。
仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

BPSアドベントカレンダー

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ