週刊Railsウォッチ(20170210)JRubyやRubiniusの配列への追加はスレッドセーフではないほか

こんにちは、hachi8833です。今週はJavaScriptのニュースが目につきました。

V8 JavaScript エンジン5.7がリリース


v8project.blogspot.jpより

  • パフォーマンス向上
  • ES2015の改良
  • RegExpが15%高速化
  • ライブラリの新機能
  • WebAssemblyが有効になった
  • V8 APIをさらに追加

個人的にはRegExpの高速化が気になりました。早くJavaScriptの正規表現がPCRE並になって欲しいものです。

Railsでよく使われるtherubyracerではlibv8が使われていますが、以前に比べると随分安定するようになったとの声がありました。libv8でググると当時ハマった人たちの声が多数見つかります。

現時点のレンダリングエンジン/ブラウザごとのJavascript engineがどれなのかわかりにくかったのでまとめてみました。

Blink(Chrome、Opera)
V8
Gecko(Firefox)
SpiderMonkey
WebKit(Safari、 PhantomJS)
JavaScriptCore(Nitro)
Trident(IE、Edge)
Chakra(オープンソースのChakraCoreもある)

JavaScriptスプレッド演算子の技6種

JavaScriptのスプレッド演算子はたとえば以下のようなものです。

//javascript spread operator
var arr1 = ['two', 'three'];
var arr2 = ['one', ...arr1, 'four', 'five'];

Rubyでの*による配列展開と少し似た動作ですね。Rubyではスプラット演算子(splat operator)と呼ばれることもあります。

一同Rubyのスプラット演算子に慣れていることもあってJavaScriptのスプレッド演算子にどよめきの声がありました。Ruby(とPerl)では...といえば範囲演算子なので、JavaScriptのこの記法にはとまどいを感じる人も多かったようです。

morimorihogeさんがJavaScriptの演算子の優先順位をその場で調べたところ、...代入よりも低くなっていました

なお...という記法はJavaC++にもあるそうなので、これらが由来かもしれません。

ActiveRecord reflectionの改良にともなってscope_chainが非推奨に

tenderlove氏のPRがすっととおりました。map().flattenよりflatten_mapの方がいいよというどこかで見た追伸もありました。

なお社内で聞いてみたところ、scope_chainを使ったことのある人は見当たりませんでした。

miniTestでテスト実行中の警告表示オプションを追加

miniTestのテスト実行中にワーニングを表示するかどうかを-w--warnings)オプションで指定できるようになったとのことです。

ActiveRecord::SerializationTypeMismatchで、エラーの発生した属性を知らせるようになった

修正されたのはdeserializerではなくserializerでした。「エラーを出すのは普通deserializerでは?」と思って一同で追ってみると、serializerで処理できないデータをserializeしようとしたときのエラーでした。

なおActiveRecordのserializerで使われるデフォルトのcoder(データ形式)はyaml_columnです。

PostgreSQL向けのcolumn_definitions()クエリをシンプルに書き直して高速化

変更箇所ではサブクエリがLEFT JOINに修正されています。

through_proxyがリセットされないことがある問題を修正

コミットメッセージより:

has_one :throughアソシエーションをnilにするとthrough_recordはdestroyされるが、reloadresetを明示的に呼ぶまでthrough_proxyでの読み込み対象に含まれてしまう。

through_proxyがリセットされないと、destroyした読み込み対象がfrozenのままになり、新規レコード作成時にRuntimeError: Can't modify frozen hashが発生する。

RuntimeErrorエラー回避のため、create_through_recordでdestroyされたthrough_recordを再読込する必要がある。

Sidekiq 5.0.0beta1がリリース

Sidekiqはバックグラウンド処理で広く使われているgemです。Rails 5.0との相性が改良され、Ruby 2.2.2未満のサポートが終了しました。

リリースノートより

  • ジョブのログ出力やリトライをSidekiq::Processorで直接扱うようになる
  • Delayed Extension API(delay、delay_in、delay_until)がデフォルトで無効になる
  • quiet signalをUSR1からTSTPに変更してJRubyに対応
  • Rails 3.2とRuby 2.1のサポート終了
  • JSONが壊れている場合に即時終了

Sidekiqのオープンソース版gemLGPLなので普通に利用できますが、バッチやマルチプロセスといった機能は有料です。

resque gemで間に合うことも多いかもしれませんね。

Ruby Object Mapper(ROM)3.0がリリース

ROMは、ActiveRecordのO/Rマッピングのような感じでデータをオブジェクトとして扱うためのgemです。APIリストを見るとcsvyamlなどさまざまなデータに対応しています。

それにしても「ROM」という名前はググりにくいですね。

Lite Cable: Railsなしで動くActionCable実装

JavaScriptで書かれています。ActionCableのAPIだけ欲しいならRailsでやるより軽くてよいかもしれないという声もありました。

Lite Cableはオープンソースですが、製品版のAny Cableもあります。ページをスクロールしたときのマスコットの動きがかなりかわいくて、私の中で一気にポイント上がりました。


http://anycable.io/より

ActionCableはRails以外でも注目を集めているようです。みんなこういうのが欲しかったということなのかもしれません。

Rubyのnilを駆逐する2つの方法(スクリーンキャスト)

nilを使わずに書くコツを紹介しています。スクリーンキャストですが下にコードと解説があるので普通に読めます。

そういえばいっときnull安全という言葉が駆け巡ったり炎上したりしてました。

「Rubyistは割りとnilに寛容かも」「nilが飛んでくることに慣れすぎてしまうのも良し悪し」「Javaのnullと違ってRubyのnilオブジェクトだしずっとタチがよいよね」という声もありました。

Rubyのハッシュは2.4で3倍速くなってる

昨年の週刊Railsウォッチで取り上げた、Ruby 2.4のハッシュで導入されたオープンアドレス周りをがっつり解説しています。かなり歯ごたえありそうな記事です。


Behind the scenes of hash table performance in ruby 2.4より

Percona Migrator: MySQLマイグレーション用ActiveRecordアダプタ

Percona Toolkitに含まれているpt-online-schema-changeコマンドを使ってActive RecordでMySQLのスキーママイグレーションを支援するツールです。

RailsエンジニアがReactを学ぶべき理由

おぴによん記事です。リンク先にあるmatzとリチャード・ストールマンとおぼしきツーショットがコラになってることの方に注目が集まってました。以下はオリジナルです。


https://en.wikipedia.org/wiki/Yukihiro_Matsumoto#/media/File:Matz.jpgより

RubyのGIL(global interpreter lock)問題を考える

最初Learn how to achieve parallelism with Ruby MRI using I/O bound threadsにしようかと思ったのですが、同記事でリンクしていたこの記事の方がよかったのでこちらにしました。

同記事の「30秒でわかるGIL」より:

MRIにはGIL(global interpreter lock)と呼ばれるしくみがあり、Rubyコードの実行周りをロックする。これにより、マルチスレッドのコンテキストでは一度にひとつのスレッドしかRubyコードを実行できなくなる。
たとえば8コアのマシンで8つのスレッドが動作しているとすると、一度に1つのコアしか動かないことになる。GILはRuby内部を競合状態から守り、データの破損を防ぐためにある。

GILはGVL(Giant VM Lock)とも呼ばれます。

GILの例として、配列への追加が実装によってはスレッドセーフでないことが挙げられています。

# Nobody understands the GIL より
array = []

5.times.map do
  Thread.new do
    1000.times do
      array << nil
    end
  end
end.each(&:join)

puts array.size

結果、MRIは正常に動作(「5000」が出力)しましたが、JRubyとRubinius(rbx)は正常に動作しませんでした。


Nobody understands the GILより

私の環境でも同様の結果が得られました。

TechEmpowerのWebフレームワークベンチマーク

よくあるベンチマークサイトのようですが、聞いたこともないようなWebフレームワークやWebフレームワークと呼んでいいのかどうか迷うようなエントリが大量に並んでいます。眺めて首を傾げて楽しむ感じでしょうか。


TechEmpower: Web Framework Benchmark
より

上のサイトとは関係ありませんが、こんなツイートがありました。

Go言語の現状(2017年2月)

Go 1.8リリースを来週に控え、予定されている新機能などを紹介するスライドが公開されました。

スライドに出てきたSSAって何だろうと思ったら、静的単一代入のことでした。

今週は以上です。

関連記事

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

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

Rails公式ニュース

Ruby Weekly

OpenRuby

RubyFlow

160928_1638_XvIP4h

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

この記事の著者

hachi8833

Twitter: @hachi8833 コボラー、ITコンサル、ローカライズ業界を経てなぜかWeb開発者志願。 これまでにRuby on Rails チュートリアルの大半、Railsガイドのほぼすべてを翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

BPSアドベントカレンダー

人気の記事