週刊Railsウォッチ(20171215)Ruby 2.5.0-rc1リリース、Ruby 2.4.3セキュリティ修正、Ruby 3.0で変わるキーワード引数、HTML 5.2 RECリリースほか

こんにちは、hachi8833です。クリスマスが迫るとRuby周りが忙しくなりますね。

今週のウォッチ、いってみましょう。

臨時ニュース1: Ruby 2.5.0-rc1リリース


www.ruby-lang.orgより

ついさっき出ました。実は先ほど以下のセキュリティ修正でrbenvを更新したときにrc1の文字が見えていたのでついでにインストールしちゃいました。

臨時ニュース2: Rubyセキュリティ修正リリース

今朝発表がありました。

修正内容

以下の2点です。必要な方はお早めにアップデートしましょう。

プレスリリース(ダウンロードリンクあり)


私もローカル環境とオレオレRailsアプリをRuby 2.4.3にアップデートしました。

Rails: 今週の改修

commit差分から見繕いました。

System TestにFirefox headless driverを追加

# actionpack/lib/action_dispatch/system_testing/driver.rb#67
             browser_options.args << "--headless"
             browser_options.args << "--disable-gpu"

+            @options.merge(options: browser_options)
+          elsif @browser == :headless_firefox
+            browser_options = Selenium::WebDriver::Firefox::Options.new
+            browser_options.args << "-headless"
+
             @options.merge(options: browser_options)
           else
             @options
           end
         end

         def browser
-          @browser == :headless_chrome ? :chrome : @browser
+          if @browser == :headless_chrome
+            :chrome
+          elsif @browser == :headless_firefox
+            :firefox
+          else
+            @browser
+          end
         end

つっつきボイス: 「Firefox Quantamが速くなったらしいのと関係あるのかな」

参考: Firefox Quantumが激重になる問題が発生中

非推奨メソッドがpublicに変わらないよう修正

# activesupport/lib/active_support/deprecation/method_wrappers.rb#60
               deprecator.deprecation_warning(method_name, options[method_name])
               super(*args, &block)
             end
+
+            case
+            when target_module.protected_method_defined?(method_name)
+              protected method_name
+            when target_module.private_method_defined?(method_name)
+              private method_name
+            end
           end
         end

つっつきボイス: 「お、お、こんなバグあったとは」「非推奨メソッドが削除されるまでの間ということですね」

非推奨のBigDecimal#newを削除

# activerecord/lib/active_record/connection_adapters/postgresql/oid/decimal.rb#6
      module OID # :nodoc:
         class Decimal < Type::Decimal # :nodoc:
           def infinity(options = {})
-            BigDecimal.new("Infinity") * (options[:negative] ? -1 : 1)
+            BigDecimal("Infinity") * (options[:negative] ? -1 : 1)
           end
         end
       end

つっつきボイス:BigDecimal#newじゃなくてBigDecimalになるのか」「RailsのActiveSupportなのかなと思ったらRubyの方だった」「newが非推奨になったのはなぜなんだろう?」「オブジェクトの同一性を担保するためなのかなと思ったけどnewあってもなくてもobject_id違うな↓」

追記: 「IntegerやFloatでnewできないのに合わせたんじゃないんすかね?」

RailsのSTIを修正

# activerecord/lib/active_record/relation.rb#55
-    def new(*args, &block)
-      scoping { @klass.new(*args, &block) }
+    def new(attributes = nil, &block)
+      scoping { klass.new(scope_for_create(attributes), &block) }
     end

つっつきボイス: 「STI: Single Table Inheritance」「この記事↓見るとSTI結構嫌われてる雰囲気ですね」「STIは有用なこともあると思うけど使ったことほとんどなかったナー: カラム増えるし」

参考: みんなRailsのSTIを誤解してないか!?

使われていないwebpack定数を削除

// activestorage/webpack.config.js#1
-const webpack = require("webpack")
 const path = require("path")

 module.exports = {

つっつきボイス: 「誰も使ってないので削除したそうです」

Rails

RailsのArelを使ってコンポジション可能なQuery Builderを書く(RubyFlowより)

# 同記事より
scene = Scene.new(scene_params)  
SceneQueryBuilder.new(scene).by_season  
SceneQueryBuilder.new(scene).by_episode  
SceneQueryBuilder.new(scene).by_dialogue  

つっつきボイス: 「Query Builderはよく使うし、いいパターンだと思う: ただ自分はArelじゃなくて生SQLで書くけど」「同じことをActiveRecordだけで書くのはつらくなりやすい」「Builderパターンを説明するときにはSQLを例に使うのが一番わかりやすいと思ってる: みんなもっと使おう」

[保存版]人間が読んで理解できるデザインパターン解説#1: 作成系(翻訳)

Railsのロガー記事2本: ActiveSupport::TaggedLoggingとベストプラクティス

# 元記事1より
#lib/vendor_payment_logger.rb

class VendorPaymentLogger < ActiveSupport::TaggedLogging  
  def initialize(logger)
    super(logger)
    logger.formatter = formatter
  end

  def formatter
    Proc.new{|severity, time, progname, msg|
      formatted_severity = sprintf("%-5s",severity.to_s)
      formatted_time = time.strftime("%Y-%m-%d %H:%M:%S")
      "[#{formatted_severity} #{formatted_time} #{$$}]\n #{msg}\n"
    }
  end
end  

つっつきボイス: 「最近ロガーで悩んでると聞いたので探してみました」「そうそう、某案件のロガー設計方針」「いつだったか、ロガーはオブジェクト指向的設計からはみ出しやすいって言ってましたね」「まさしく」

リレーションだけが更新されるとupdate_attributeでSQLが発行されない

Gobyの作者@st0012さんからの情報です。Rails 5のissue #25503が以下のやり取りの後未だにcloseしていないそうです。この挙動は2015年に0fcd4cで追加されたそうです。

問題点を見つけた。
changed?メソッドがリレーションの更新をチェックせず、属性の更新だけをチェックしてた。
リレーションが更新されたかどうかをチェックする何かうまい方法を見つける必要がある。個別のテストは動くのにグループになるとコケるテストがあったので、条件を少し追加する必要があった。
25503#issuecomment-250984166より大意


つっつきボイス: 「仕様なのかバグなのか?」「ActiveRecord::Persistence#update_attributeではリレーションの更新には触れてないですね」「ところで『update_attributeはバリデーションがきかないゴミだぞ』って誰か言ってた」「update_attribute(key, value) というAPIも残念」「バリデーションが効かないからゴミというわけではない(過去にやらかした経験上)」

参考: ActiveRecord の attribute 更新方法まとめ

Rubyアプリが劣化する様子をレストランになぞらえて説明する

Passengerでお馴染みのオランダPhusion社のブログ記事です。レストランに皿洗い機を導入後に処理量を増やすとどうなるかという形でサーバーのワーカーの扱いについて解説しています。


同記事より

テストにおけるstubのコスト

stubは速いしスイスイ通るし便利だけど使い所に注意という記事です。

# 同記事より
describe Order do
  let(:customer) { Customer.new }
  let(:order)    { Order.new(subtotal: 100, customer: customer) }

  describe '#total' do
    context 'a customer has fee' do
      before do
        customer.fee = 21
      end

      it 'returns the total price which includes fee' do
        expect(order.total).to eq(121)
      end
    end

    context 'a customer has no fee' do
      before do
        customer.fee = 0
      end

      it 'returns the total price without any fee' do
        expect(order.total).to eq(order.subtotal)
      end
    end
  end
end

つっつきボイス: 「単体テストだとstubを使う意味ないこと多いっすね」

Passwordless: Railsアプリでパスワードなし認証するgem

class User < ApplicationRecord
  validates :email, presence: true, uniqueness: { case_sensitive: false }

  passwordless_with :email # <-- ここ
end

つっつきボイス: 「とりあえずPasswordlessという名前はわかりやすくていいかも: Deviseに比べれば」

[Rails] Devise Wiki日本語もくじ1「ワークフローのカスタマイズ」(概要・用途付き)

ankaneさんの膨大なメモ

groupdateなどさまざまなgemを出しているAndrew Kaneことankaneさんがいろんなドキュメントをリポジトリに置いているのを見つけました。内容はRails/PostgreSQL/セキュリティ/データサイエンスなどさまざまです。


つっつきボイス: 「BPSもDocbaseにMarkdownドキュメントを社内でじゃんじゃん共有しているけど、それと同じようなノリなのかも」「publicな場所に置いているのエライ」

Markdownで書けるドキュメントコラボレーションサービスを比較する

コーディングスタイルで揉める理由

『オブジェクト指向設計実践ガイド』などでお馴染みのSandi Metz氏の記事です。

  • なぜスタイルガイドを使うのか
  • どのスタイルガイドがいいのか
  • なぜチームで反対されるのか
  • 自分流でやりたいんだけどダメ?
  • チームで合意を取り付けるには
  • 新しいスタイルガイドが性に合わないときは?

つっつきボイス: 「これはどうしてもどこかで揉めるやつ」「永遠の課題」「基本はプロジェクトの既存スタイルに沿うことにして、迷ったらスタイルガイドに沿う、と言うだけなら簡単ですけどね」

【保存版】Rubyスタイルガイド(日本語・解説付き)総もくじ

ワーカープロセスを安全に切り替える

factory_girl改めfactory_botなどでお馴染みのThoughtbot社のブログ記事です。

# 同記事より
#!/usr/bin/env ruby

STDOUT.sync = true

def info
  "PID=#{Process.pid} WORKER_VERSION=1"
end

puts "TICK: Starting process... #{info}"

trap "TERM" do
  puts "TICK: Received SIGTERM #{info}"
  sleep 5 # 重い作業を終了中ということにする
  puts "TICK: Graceful shutdown #{info}"
  exit
end

loop do
  puts "TICK #{info}"
  sleep 2 # 重い作業を実行中ということにする
end

doorkeeper: RailsでOAuth2認証するgem

OAuth2に特化した認証gemです。Railsの他Grapeフレームワークにも対応しているそうです。

# doorkeeper-gem/doorkeeperより
class Api::V1::ProductsController < Api::V1::ApiController
  before_action :doorkeeper_authorize! # 全アクションでトークンを必須にする

  # 以下アクション
end

つっつきボイス: 「doorkeeper、結構定番らしいけど初めて知ったので」「これもいい名前かな」「そうっすか?Doorkeeper.jpと紛らわしそう」

Rails Developer Meetup 2017より


railsdm.github.ioより

大盛況だったRails Developer Meetup 2017のスライドからです。参加したかったー(´・ω・`)

ふつうのRailsアプリケーション開発

とても参考になります。

yuba: Railsの抽象化支援gem

generatorで生成できます。

# willnet/yubaより
rails generate yuba:service create_artist
rails generate yuba:form artist
rails generate yuba:view_model artist_index

rancher: コンテナを継続的に管理

deppbotとtachikoma.io: セキュリティや依存関係の自動更新

Ruby trunkより

Ruby 3でキーワード引数がかなり変わる見通し

詳細は今後多少変わるのかもしれませんが、既にMatzがRubyWorld Conference 2017などでRuby 3で本物のキーワード引数を導入すると言明しているそうです。

# 以下の呼び出しは「キーワード引数」を渡す
foo(..., key: val)
foo(..., **hsh)
foo(..., key: val, **hsh)

# 以下の呼び出しは「通常の引数」を渡す
foo(..., {key: val})        # {} で囲まれている
foo(..., hsh)
foo(..., {key: val, **hsh}) # {} で囲まれている

# 以下のメソッド定義は「キーワード引数」を受け取る
def foo(..., key: val)
end
def foo(..., **hsh)
end

# 以下のメソッド定義は「通常の引数」を受け取る
def foo(..., hsh)
end

Ruby 2のキーワード引数はHashオブジェクト(キーはすべてシンボル)の通常の引数であり、最後の引数として渡されている。この設計を選んだのは互換性のためだったが、かなり複雑になっていて、動作が直感的にならない多くのエッジケースの原因になっていた。
Ruby 3ではキーワード引数は通常の引数と完全に分離される(ブロックパラメータが通常の引数と完全に分離されているのと同様に)。
この変更によって互換性が失われる。キーワード引数を渡したり受け取ったりする場合は、常に({}などで囲まない)むき出しのシンボル値かdouble-splat**が必要になる。
次のような移行パスを考えている:
* Ruby 2.6か2.7あたりで警告を出すようにする: 通常の引数がキーワード引数と解釈可能な場合(またはその逆)
* Ruby 3.0で新しい文法に完全に移行する
#14183より大意


つっつきボイス: 「最初#14176 Unclear error message when calling method with keyword argumentsにしようかと思ったんですが、その後でこのissueが流れてきたので」「Railsも順次対応不可避…ゴク」「実は@st0012さんがちょっと前からGobyのキーワード引数周りの仕様で矛盾に突き当たって悩んでいるんですが、これを見たら無理もないかも」「本当のキーワード引数

Ruby 2.0.0リリース! – キーワード引数を使ってみよう

そこからsplat演算子(*)やdouble-splat演算子(**)の話題になりました。

「splat演算子って、引数とパラメータのどっちにも置けるからまたややこしい」「正直ぱっと見て分からないw」

参考: Rubyの配列展開 *[a, b, c]

Ruby

Ruby 2.5でStructにkeyword_init: trueでキーワード引数が使える

こちらもキーワード引数にちょっと絡みます。

Foo = Struct.new(:a, :b, keyword_init: true)
Foo.new(a: 1, b: 2) #=> #<struct Foo a=1, b=2>

つっつきボイス: 「これはとてもよい」「最初ハッシュが渡せるのかと思ったらキーワード引数だった」「とはいうもののStructにするより普通にクラス書いちゃうことの方が多い: Structって規模感で悩むのと、ダメな使い方になる可能性もあるんで」「Struct#newインスタンスを継承すべからずとかですね」

Rubyスタイルガイドを読む: クラスとモジュール(2)クラス設計・アクセサ・ダックタイピングなど

シングルトンクラスの本当の使われ所

私たちが普通クラスメソッドと呼ぶものは、技術的には、それぞれのシングルトンクラスで定義されたクラスオブジェクトの(シングルトン)インスタンスメソッドです。
同記事より


www.puzzle.chより


つっつきボイス: 「この図↑を見た限りでは、シングルトンクラスも加味すると継承パスはこんなふうに二本立てともみなせるということかな」

RubyConf 2017で発表したお: Rubyで2Dゲーム作った

記事のスライドの見せ方が見事です。


www.blacktm.comより


つっつきボイス: 「↑Apple IIがつい懐かしくって」

最近のYARV-MJIT


つっつきボイス: 「70fpsはoptcarrotのパフォーマンスでしょうね」

Rubyと型


つっつきボイス: 「Matzと_ko1さんの二人がこんなに手こずるなんて、型理論ってどんだけ難しいんだと思ってこの翻訳記事↓見つけました」

参考: 「型」の定義に挑む

「話がバートランド・ラッセルの数理論理学から始まってて、抽象度むっちゃ高い」「きわめつけは以下↓: 厳密に定義しすぎると発展を妨げるって」「(数学科出身につき)それ気持ちわかるわー」「エンジニアの発想じゃなくて数学者の発想だなーと思いました」

“型の定義とは何か?” この質問に明確かつ正確な回答を与えられれば、そこから生じる多くの誤解や無意味な議論を避けることができる。しかし、この質問に対して、そのような明確かつ正確な回答を持ってしまった場合、科学の前進を鈍化させ、”知識の成長を妨げ”、”調査の道筋を既知の狭いチャネル内に引き入れてしまう”ことにもつながりかねない。
postd.ccより

参考: Wikipedia: 型理論

JavaScript

LeaderLine: 指示線を描画するJSライブラリ


github.com/anseki/leader-lineより


つっつきボイス: 「これ大好きー: だいぶ昔にこういうのを力技で実装したときはうまくいかなかったのを思い出した(´・ω・`)」

parcel人気急上昇?

10日しないうちに★10,000に迫る勢いです。

github.com/parcel-bundler/parcelより

設定ファイルなしでも動くというのが殺し文句のようです。


つっつきボイス: 「JS環境選びってギャンブル」「今からでも遅くはない?」

参考: webpack時代の終わりとparcel時代のはじまり

図と例で学ぶawaitasyncFrontend Weeklyより)


nikgrozev.comより


つっつきボイス:asyncとかpromiseはほんと面倒」

JavaScript: 5分でわかるPromiseの基礎(翻訳)

mapforEachの違い

パフォーマンスも含めて比較した記事です。

// 同記事より
arr.forEach((num, index) => {
    return arr[index] = num * 2;
});
// arr = [2, 4, 6, 8, 10]
let doubled = arr.map(num => {
    return num * 2;
});
// doubled = [2, 4, 6, 8, 10]

つっつきボイス:map()forEach()はRubyの#map#eachとだいたい同じようなものだと思ってる」「他の言語でforeachを見た気がするけどどの言語だったかな…」

参考: Wikipedia-ja Foreach文

CSS/HTML/フロントエンド

HTML 5.2 RECがリリース

今年10月に出たHTML 5.1 2nd Editionの立場は…

目立つ部分だけ目次レベルでざっとdiff取ってみました(左がHTML 5.2、右がHTML 5.1 2nd Edition)

最近の非同期CSS読み込み(Frontend Weeklyより)

今ならrel="preload"でJSなしでできるということです。

<link rel="preload" href="mystyles.css" as="style" onload="this.rel='stylesheet'">

はじめてのCSS Gridレイアウト(Frontend Weeklyより)

CodePenを多用して説明しています。

See the Pen CSS Grid: Calendar by Geoff Graham (@geoffgraham) on CodePen.


つっつきボイス: 「そういえばbabaさんが『gridって直下の要素しかgridできないのが不便なんですよね』って言ってました」「display: flex;が見えてあれ?と思ったけどliの中だけだった」

GoogleがSEOスターターガイドを改訂

肝心のガイドはまだ日本語になっていません。

Unicode Consortiumが追加待ちのグリフにフィードバックを募集


blog.unicode.orgより


つっつきボイス: 「文字が全部鼻に見えるw」「これレビューできる人世界に何人というレベルでは」

今気づきましたが、17372r-n4923-dam1-chart.pdfに旧かな文字まで並んでいて絶句してしまいました。もはや誰得。


17372r-n4923-dam1-chart.pdfより

その他

Microserviceアーキテクチャのパターン


microservices.ioより

昨日BPS社内のエンタープライズ・アーキテクチャ勉強会でMicroserviceのアーキテクチャに言及されたので探してみました。

エンタープライズアプリケーションアーキテクチャパターンを読む: 1.概要

Googleが動画を自動で漫画に変換するアプリを実験公開


research.googleblog.comより


つっつきボイス: 「うう、すげー」「コマ割りまでやってる」「今後結婚式に出席したらきっと山ほど見られますよ」

参考: Google、動画を自動で漫画化する実験アプリ公開。AIポートレートカメラマンやスクラッチ動画生成も

Recho: SlideShareなどにTwitterレスを表示できるChrome拡張


つっつきボイス: 「ほとんどニコ動」

go-torch: Goプログラムをブラウザでビジュアルプロファイリングするツール


つっつきボイス: 「この間もこんなグラフ見ましたね」「名前ど忘れ…frame graphだった」

参考: Go言語のプロファイリングツール、pprofのWeb UIがめちゃくちゃ便利なので紹介する

コードをフェンスの向こうに放り投げる

正規表現のよさげな本

番外

Ruby Tuesday


つっつきボイス: 「asakusa.rbが火曜日開催だから?」「そういうことか」

中国語にひらがなの「の」が絶賛混入中

人間デコーダー

写真は残念ながら削除されたようです。


つっつきボイス: 「この郵便屋さんものすごく優秀なんじゃ」「普通迷宮入りですよね」

むやみになつかしい感


つっつきボイス: 「大昔にTK-80↓の横でラジカセでFM聴いてたら実行/停止に応じていろんな音階が出たのをつい思い出しちゃって」

磁石とクリップ


今週は以上です。

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

週刊Railsウォッチ(20171208)最近のRailsフロントエンド事情、国際化gem、mallocでRubyのメモリが倍増、るびま記事募集ほか

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

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

Ruby 公式ニュース

Rails公式ニュース

Ruby Weekly

RubyFlow

160928_1638_XvIP4h

Frontend Weekly

frontendweekly_banner_captured

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

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

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ