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

週刊Railsウォッチ(20170120)Ruby 2.5.0 devリリース、古いMySQLのサポート終了、uniqメソッドが削除ほか

こんにちは、hachi8833です。

年が明けてRails公式ニュースの更新情報が2回分たまっていたので放出します。Rubyそのものの更新情報も多数目につきました。

Ruby 2.5.0 devが公開

早くもRuby 2.5.0 devが公開されました。

早速いつものようにruby-buildを更新してrbenvでインストールしました。

cd ~/.rbenv/plugins/ruby-build
git pull
rbenv install 2.5.0-dev

rbenv/ruby-buildリポジトリのWatchをオンにしておくと、更新をメールですぐ知ることができて便利だと思いました。

Rails 4.2がRuby 2.4で動作するようになった

早くもちょっとうれしいニュースです。

ActiveRecord::CounterCacheのメソッドでタイムスタンプ更新をtouch:でオン/オフできるようになった

「この修正はありがたい」という声があがりました。

JSON属性値のシリアライズでnilをJSONのnullではなくSQLのNULLに修正した

5.0.1でのPostgreSQL向けの修正です。PostgreSQLでJSON型を使っているならRailsアップグレードなどでチェックが必要かもしれません。

When data are persisted into the DB nil is translated to 'null', not SQL NULL. This leads to several problems:
(略)
I think the preferred fix is to map nil to SQL NULL, exactly as how it used to work in Rails 4.x.

Rails 4.xのときの挙動(nilをSQLのNULLにマップ)に戻したということです。

2016年9月にマージされており、Rails 5.0.1には既に反映されていますが、5.0から5.0.1にアップグレードするときには気にしておく必要がありそうです。

MySQL 5.0.xがRailsでサポート終了

ActiveRecordでは、今後MySQL 5.1.10以降のみがサポートされます。古めのLinuxディストリに同梱されていたMySQLのバージョンには一応注意しておくのがよさそうです。

なお、現時点のMySQL最新版は5.7.17です。

GET以外のHTTPリクエストでもcookiesを更新するようになった

Previously, cookies were only updated on GET requests. Now we will update the helper for all requests, as part of process.

PRそのままですね。ヘルパーは今後すべてのHTTPリクエストでcookiesを更新します。

Railsから削除された非推奨コード

削除されたのは以下です。

  • Rakeのdb:test:clone
  • 設定のserve_static_filesstatic_cache_control
  • ActiveRecordのuniquniq!uniq_valueinsert_sqlupdate_sqldelete_sql

ActiveRecordの#uniqが非推奨になった件についてはRailsガイドの5.0リリースノートにもありますね。

Ruby 2.5では定数の参照がトップレベルの定数にフォールバックしなくなる

上のリンクは、Ruby側での変更に合わせたRailsの変更です。

ActiveRecordのpool_from_any_processが最新のspecを参照するようになった

コネクションプールでプロセスが多数forkしたときにspec_nameが古いものから参照していて非効率だったのを、新しい方から参照するようになりました。

Time/Date/DatetimeのサブクラスでnewしたときにサブクラスではなくTime/Date/Datetimeを返していたのを修正

これに関連する#27614RubyZipというgemに言及されていて、そういえばよく似た名前のziprubyというgemはさっぱり更新されてないなー、などの話題が出ました。

Railsで月と年を含む期間の扱いを修正

BPS社内で今回最も盛り上がった修正でした。期間(duration)の扱いは簡単ではないことを思い知らされます。

修正前は、現在時刻次第で以下がエラーになることがあったようです。

ActiveSupport::Duration.parse(2.months.iso8601) == 2.months
ActiveSupport::Duration.parse(3.years.iso8601) == 3.years

ChangeLogをざっくり要約しました。

  • 期間の計算を「秒」ベースとした
  • これにより、グレゴリオ暦の365.2425日/年という値から400年に1度の「非うるう年」を割り出せる
  • 月の長さは年の長さから定義されるのだから、12.months == 1.yeartrueになるべき
  • 逆に30.days == 1.monthは定義上ナンセンスであり、falseになるべき

active_support/duration.rbの更新部分が物語っています。

    PARTS_IN_SECONDS = {
      seconds:                               1,       # parseに備えてハッシュの各値を秒に変換する
      minutes:                              60,
      hours:                           60 * 60,
      days:                       24 * 60 * 60,
      weeks:       7            * 24 * 60 * 60,
      months:  ((365.2425 / 12) * 24 * 60 * 60).ceil, # 「1年」とは常に「12か月」であり、日数で表すものではない
      years:    (365.2425       * 24 * 60 * 60).ceil, # 400年に1度の「非うるう年」を扱えるグレゴリオ暦ベースの年の長さ
    }.freeze

一同で調べたところ、365.2422は、グレゴリオ暦より新しい修正ユリウス暦が由来のようです。

上のコードはグレゴリオ暦の定義に沿うと割り切っていますが、1年の長さ(太陽年)にこだわりだすと実はきりがないのでした。以下が参考になりそうです。

グレゴリオ暦は1年の長さを365.2425日としているので、太陽年より0.0003日長い。このため約3000年ほどで1日のずれが生ずる、とされる。しかし、冬至年は近日点移動の影響で376.2427日ほどなので、これはグレゴリオ暦の1年よりやや長い。したがってグレゴリオ暦では冬至は次第に遅れることになる。近日点は3000年の間に51°ほど動くが、それでも冬至年が太陽年より長めという傾向は変わらない。
一方で夏至年は太陽年よりさらに短いので、こちらは3000年で2日ほども早くなる。そして春分年、秋分年は太陽年に近いので、定説どおり3000年で1日ほど早くなる。つまり、「3000年で1日」というのは平均での話で、詳細に見れば季節によって多少違うのである。
「冬至年」についてより

ついでながら、地球の自転速度って潮汐力やら何やらで少しずつ遅くなっているはずですよね...

今後はActiveRecordのclass_nameにクラスオブジェクトではなく文字列を渡すこと

リフレクションの動作を見直して不必要なクラスを追加しないようにし、依存の循環を避けるようになりました。それにともなってclass_nameにクラスオブジェクトを渡すのは非推奨になりました。

Please pass the class name as a string:belongs_to :client, class_name: 'Company'

環境変数envが空文字列の場合のRails.envのデフォルト値がdevelopmentになった

ついこの間のTechRacho記事『[Rails5] Active Support Core ExtensionsのString#inquiryでメタプログラミング』で扱ったString#inquiryとちょうど絡んでいますね。

Ruby 2.xのRefinement機能でArray#sumにモンキーパッチを当てた

Ruby 2.xのRefinementという機能についてはコミッターみずからによる当時の記事が参考になります。

Ruby 2.4でduplicable?の戻り値が変更された

今回はじめて知りましたが、Ruby 2.4からNilClass/FalseClass/TrueClass/Symbol/Numericクラスはdupできるようになったんですね。これに合わせてactive_support/core_ext/object/duplicable.rbが改修されたとのことです。

ネストしたRailsエンジンでのrails generateの動作を修正

以前は::などの記号で問題が生じていました。

Rubyでファイル名を操作する場合はFile#joinが定番なのですが、意外にも改修前のコードでは使われていなかったのに一同気づきました。

Onigmoに新機能追加

Onigmoに以下のような非包含オペレータ(?~)が追加されたそうです。ご存知のとおりRubyの正規表現エンジンはOnigmoなので、遠からずRubyでも使えるようになると思います。

(?~お前にだけはマッチしたくない)

ご存知のとおり、正規表現はネガティブマッチが苦手です。「〜を含まない」を正規表現だけで表そうとすると信じられないぐらい長い正規表現になってしまい、パフォーマンスも残念な感じになってしまいます。

従来はlook ahead/behindの否定表現(?!なんちゃら)(?<!なんちゃら)で切り抜けることがほとんどでしたが、それさえ使えない正規表現エンジンも少なくありません。

正規表現の性質上パフォーマンスは期待しないほうがよさそうですが、読みやすくなるだけでも助かります。

関連論文『正規表現における非包含オペレータの提案』も非常に興味深い内容なので、合わせてご覧ください。

追伸: 既存の正規表現で非包含っぽいマッチを書く

ところで今回調べていて、既存の正規表現でも似たようなものが書けることを初めて知りました。他に方法がないときに使ってみようと思います。

/(?:(?!お前にだけはマッチしたくない).)*/  # その1
/((?!お前にだけはマッチしたくない).)*/    # その2

Swagger: RailsアプリのAPIフレームワーク

今週号はRails公式ニュース以外は控えめにしました。

Railsアプリのドキュメント化ツールかと思ったら、Swaggerは自体はAPIフレームワークで、その一環としてswagger-doc gemがあることを知りました。


sitepoint.comの記事よりより

npm版のswagger-docも見つけました。

Castaway: Rubyで制御できる動画プレゼン

Twitterで拾いました。スライドのコンテンツ作成とナビゲーションをRubyコードで書けます。

YouTube動画を見るのが早いと思います。

Googleが新しい圧縮ライブラリDracoを発表

非可逆圧縮かどうかが書いてありませんが、この圧縮率からして非可逆っぽい気がします。

ユーザー入力で使われると問題を起こしがちな文字列リスト

これ、テストデータとして普通に役に立ちそうです。ゼロ幅スペースなどの意地悪な文字列がずらり集められています。


Big List of Naughty Stringsより

Standard File: 企業やサービスを超えて利用できるアカウントプロトコル

StandardFileというオープンなアカウントプロトコル(GNUライセンス)に沿ったサーバーをRubyで実装したということです。https://app.standardnotes.org/では、このプロトコルを使ったEvernoteっぽいサンプルアプリを見ることができます。

サーバーに保存する前に必ずローカルで暗号化され、アカウントのプロバイダを自由に選べる(自分で運営してもよい)そうです。一見、大学のプロジェクトのようですがそうでもないらしく、このひとがほぼ一人でやってるようです。謎です。

今週は以上です。

関連記事

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

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

Rails公式ニュース

Ruby Weekly

Hacker News

160928_1654_q6srdR

Github Trending

160928_1701_Q9dJIU


CONTACT

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