週刊Railsウォッチ(20170609)ついにtherubyracerからmini_racerへ、注意しないとハマるgem、5.1でのVue.jsとTurbolinksの共存ほか

こんにちは、hachi8833です。暦では梅雨ですが近年のこの時期、どうも天候がはっきりしませんね。

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

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

ついにtherubyracerを置き換え: 後任はmini_racer

therubyracerのV8エンジンのバージョンが古いことはRailsウォッチでもお知らせしましたが、2013年のChrome 31並に古かったんですね。古いV8の脆弱性が見過ごせない状態になったのがきっかけだそうです。

PRでも喜びの声があがっています。「mini_racerの方が速いし安定してるし」

つっつきボイス: 「昔バージョン依存が強かった時代に泣かされた人、多かったよねー」「therubyracerって、入れろ入れろってしょっちゅうメッセージ出るとその誘いに乗っちゃったり」「Gemfileにもコメントアウト状態ですがありますね」「mini_racerでRails 5.1をインストールしたときにyarnって動くんだろか?やっぱりnodeも別途必要なんだろか?」

RailsのJavaScriptの悩みは尽きません。

class_attributeにデフォルト値を指定するオプションを追加

DHHがこんな感じでガンガン修正しました。

-        class_attribute :periodic_timers, instance_reader: false
-        self.periodic_timers = []
+        class_attribute :periodic_timers, instance_reader: false, default: []

つっつきボイス: 「確かに前はこれできなかったなー」「これでちょっと読みやすくなるかも」

前回の曜日と次の曜日を取れるAPIをActiveSupportに追加

pixeltrix氏(私は勝手に「先生」と呼んでます)が「next_weekとどう違うの?こういうのがいっぱい増えすぎてもうこっちも追えなくなってるんだよね」「たぶんこれはよくない」といったんピシャリとcloseしましたが、「いやいや、そうじゃなくって前回と次回の曜日です」「そうか、しかしメソッド名がよくないなー」といったやりとりを経てめでたくmergeされました。

私も当初読み違えてしまいましたが、morimorihogeさんが「テストコード見たら一発っすね」と大画面に映してくれました。

# activesupport/test/core_ext/date_time_ext_test.rb
  def test_next_occur
    datetime = DateTime.new(2016, 9, 24, 0, 0) # saturday
    assert_equal datetime.next_occurring(:monday), datetime.since(2.days)
    assert_equal datetime.next_occurring(:tuesday), datetime.since(3.days)
    assert_equal datetime.next_occurring(:wednesday), datetime.since(4.days)
    assert_equal datetime.next_occurring(:thursday), datetime.since(5.days)
    assert_equal datetime.next_occurring(:friday), datetime.since(6.days)
    assert_equal datetime.next_occurring(:saturday), datetime.since(1.week)
    assert_equal datetime.next_occurring(:sunday), datetime.since(1.day)
  end

  def test_prev_occur
    datetime = DateTime.new(2016, 9, 24, 0, 0) # saturday
    assert_equal datetime.prev_occurring(:monday), datetime.ago(5.days)
    assert_equal datetime.prev_occurring(:tuesday), datetime.ago(4.days)
    assert_equal datetime.prev_occurring(:wednesday), datetime.ago(3.days)
    assert_equal datetime.prev_occurring(:thursday), datetime.ago(2.days)
    assert_equal datetime.prev_occurring(:friday), datetime.ago(1.day)
    assert_equal datetime.prev_occurring(:saturday), datetime.ago(1.week)
    assert_equal datetime.prev_occurring(:sunday), datetime.ago(6.days)
  end

つっつきボイス: 「会話なんかだとよく『じゃ作業は次の土曜日にしましょうか』『この前の日曜は何してた?』みたいなこと言うけど、そういうことかー」「こういうメソッドはあれば使うかなー」「週の境目を気にしなくて済むのはいいかも」

補足: 曜日の雑学

お気づきの方も多いと思いますが、英語には「曜日」を1語でぴたりと表す用語がありません。「day of week」という何だか苦し紛れな言い方しかなくて、こういうときに本当に紛らわしいですね。「day of week」だとスマホでも場所取るし。コンピュータ関連ではDOWと略すこともあるらしいですがさっぱり定着しません。weekdayは「平日」なので使えそうで使えません。

日本語の曜日は言うまでもなく古代中国の七曜が由来で、もっぱら占い用でした。日本にもたらしたのは空海なんだそうで、七曜を使ったに違いない陰陽師がもてはやされたのはもっと後みたいです。

曜日の命名には主要な惑星・恒星がマッピングされていることがひと目でわかります。しかも「曜」という字はこの意味でしか使わない言葉なので取り違えも少ないと思います。

ひるがえって英語の曜日はというと、Sunday、Saturday、Mondayあたりはかろうじて「太陽、土星、月」かなという感じですが、Tuesday、Wednesday、Thursday、Fridayは北欧神話が起源というハイブリッドです。

月名も、日本は1月2月と数字化されているのでループで回しやすいのですが、英語圏は未だに「January、February、March」と、旧暦の「睦月如月弥生」と大して変わらない世界なんですね。

英語圏で月名を01や02で表すのはlsコマンドやログのように「そうするしかない場合にしぶしぶ使う」感じで、一般には英語圏で月を数字で表すのはえらく嫌がられます。英語には日本語のような「月」「日」「曜」「時」「分」「秒」といったサフィックスがなく(期間を表す場合は10 daysや20 secのように書けますが)、月なのか日なのか時なのか分なのかわかりにくいのでしょうがないかもしれません。

なお中国語では月曜火曜みたいな表記は随分昔に廃れてしまい、星期一(=月曜)、星期二(=火曜)のように数値で表します。惑星・恒星とのマッピングは捨てられました。合理的かなと思う一方、年月日とベタで2017/01/01(01)みたいに並べるとかえってわかりにくい気もしますが。

Vue.jsとTurbolinksを共存させる方法

検索で見つけました。vue-turbolinksをyarnで導入して以下のようにするのがポイントだそうです。なお以下のコードはvue-turbolinksのページから引用しました。

// Vueを使う場合
import TurbolinksAdapter from 'vue-turbolinks';

document.addEventListener('turbolinks:load', () => {
  var vueapp = new Vue({
    el: "#hello",
    template: '<App/>',
    mixins: [TurbolinksAdapter],
    components: { App }
  });
});
// 特定ページでのみVueを使いたい場合
import TurbolinksAdapter from 'vue-turbolinks';

document.addEventListener('turbolinks:load', () => {
  var element = document.getElementById("hello")
  if (element != null) {
    var vueapp = new Vue({
      el: element,
      template: '<App/>',
      mixins: [TurbolinksAdapter],
      components: { App }
    });
  }
});

morimorihogeさんがGitHubリポジトリでvue-turbolinksのソースを開けてみると、ソースはたったこれだけでした。

// https://github.com/jeffreyguenther/vue-turbolinks/blob/master/index.js より
function destroyVue() {
  this.$destroy();
  document.removeEventListener('turbolinks:before-cache', destroyVue.bind(this))
}

var TurbolinksAdapter = {
  beforeMount: function(){
    if (this.$el.parentNode) {
      document.addEventListener('turbolinks:before-cache', destroyVue.bind(this))
      this.$originalEl = this.$el.outerHTML;
    }
  },
  destroyed: function() {
    this.$el.outerHTML = this.$originalEl;
  }
};

export default TurbolinksAdapter;

つっつきボイス: 「Turbolinksがあるとこんな感じで他のJSライブラリのイベント発火とか面倒みないといけないのがつらいねー」「前に自力でやったなー、これ」

参考: RailsでVue.jsを使う方法

少し前のものも多いですが、Vue.jsとRails関連の英語記事やサンプルをメモします。

気をつけないとハマるかもしれないgem 5+1種(RubyFlowより)


blog.rubyroidlabs.comより

先週のウォッチで紹介した19種のおすすめgem記事と同じrubyroidlabs.comの記事です。

  • devise_token_auth
  • sidekiq-unique-jobs
  • axlsx
  • whenever
  • dwolla-ruby
  • rails_admin + will_paginate

つっつきボイス: 「言いがかりに近いのもある気がするなぁ、ちゃんと使ってないだけだったりとか」「axlsxはメモり食うかもしれないけどこの手のgemとしてはいい方だと思う: 巨大CSV食わす感覚で巨大XLSX食わせるものじゃないと思うし」「rails_adminは同意: 管理画面系はだいたいろくなことにならない」「kaminariがあるんだからwill_paginateいらないっしょ」

そこからRails以外も含めたジョブ管理の話題に広がりました。

つっつきボイス: 「sidekiq-unique-jobsに限らず、ジョブ管理はだいたい大変になるよね」「消えていいジョブなんて普通はないし」「リトライを繰り返した末あきらめたりとか、リトライ中の状態がわからなかったり」「ひどいのになると詰まったジョブを殺して新しいジョブを作ってリトライする凶悪なジョブ管理もあったりとか」「ActiveJobはジョブ管理そのものじゃなくてインターフェイスを統一するものだし」

参考: Railsガイド: Active Jobの基礎

RubyのサーバーをRedisでMutexっぽく同期してみたお

http://blog.cloud66.com/より

Twitterで見かけた記事です。
RubyにはMutexというクラスがありますが、これは単独のプログラム内でのロック用です。
ここではRedisのlock機能を使って、Rubyアプリ間でMutexと同じような感じでロックを実現してみたのだそうです。

# http://blog.cloud66.com/ruby-mutex-mayhem-part-2/より
# cross-process/cross-server mutex
class RedisMutex

  attr_accessor :global_scope,
                :max_lock_time

  LOCK_ACQUIRER = "return redis.call('setnx', KEYS[1], 1) == 1 and redis.call('expire', KEYS[1], KEYS[2]) and 1 or 0"
  KEY_SPACE_PREFIX = '__keyspace@0__:'
  DEL_OR_EXPIRE_EVENTS = Set.new(['del', 'expired'])

  def initialize(global_scope, max_lock_time)
    # the global scope of this mutex (i.e "resource")
    @global_scope = global_scope
    # max time in seconds to hold the mutex
    # (in case of greedy deadlock)
    @max_lock_time = max_lock_time
  end

  def synchronise(local_scope = :global, &block)
    # get the lock
    acquire(local_scope)
    begin
      # execute the actions
      return block.call
    ensure
      # release the lock
      release(local_scope)
    end
  end
  ...

つっつきボイス: 「どうせならdrbでやりましょうよw(本当は大変だけど)」「drbって知らなかったー」「Rubyのネットワークプログラミングって実はかなり強力なんですよね」「synchroniseとかJavaっぽいw」

今気づきましたが、synchroniseだと英国風の綴りですね。米国だとsynchronizeです。ヨーロッパだと英国風のスペルが使われがちです。

Rubyリファレンスマニュアル: library drbには、「dRuby でインターネット上に公開するサービスを作るべきではありません」みたいなことが書いてあったりしますが、これはたぶん「インターフェースをインターネットに全開放するサービスを作るべきではない」ということなんだと思います。インターフェースをネットにフルで開放してはいけないのはdRubyに限りませんよね。

Railsconf 2017で仕入れたパフォーマンス関連の話(RubyWeeklyより)

5月にアリゾナで開催されたRailsconf 2017についてはRailsウォッチでもお知らせいたしましたが、その中からパフォーマンスに関連するメモ書きがたっぷり掲載されています。Railsconf 2017はかなり充実していたことがうかがえます。

  • Bootsnap
  • フロントエンドのパフォーマンス
  • アプリサーバーのパフォーマンス
  • rack-freeze
  • snip_snip
  • Rubyのinline threshold
  • 「あなたのアプリの設定は間違っている」by Heroku
  • パフォーマンスパネル
  • HTTP/2
  • Ruby Performance Research Group

「来年もカラオケやるぞー」と締めくくってます。

つっつきボイス: 「これけっこういいなー、量多いけど」「翻訳があったら読みたい」

RedCard: Ruby実装やバージョンを検出・制限するgem(RubyWeeklyより)

実行中のRubyの実装やバージョンの取得や、バージョンが合わない場合にexceptionを投げるgemのようです。

# MRIとRubiniusを1.9に限定
RedCard.verify :ruby, :rubinius, "1.9"


if RedCard.check "1.9.3", "2.0"
  # 1.9.3や2.0でのみ動くコードをここに書く
end

# Ruby 1.9とRubiniusを必須にする
require 'redcard/1.9'
require 'redcard/rubinius'

つっつきボイス: 「Railsならbundler経由で実行するときにGemfileのruby-versionを見るから不要かなー」

EmberとRails Stackでスモークテストを書く

同じサイトの別記事です。Ember.jsは「A framework for creating
ambitious web applications.」と謳っているように、かなり凝ったことができるMVCベースの欲張りさんなJSフレームワークです。メガネのタヌキみたいなのがマスコットです。


https://www.emberjs.com/より

この記事ではcapybaraやSelenium-webdriverなどを使い、Ember.jsでやらかしがちなエラーをいち早くキャッチする方法などを解説しています。

# https://blog.rubyroidlabs.com/2017/03/smoke-rails-ember/ より
#features/login.feature
@javascript
Feature: Login
  When a user visits "/", they should see form to login
  Scenario: User views login-page
    When I visit "/"
    Then I should see "SIGN IN"

#features/steps/login.rb
When(/^I visit "(.*?)"$/) do |path|
  visit path
end
Then(/^I should see "(.*?)"$/) do |text|
  page.should have_content(text)
end

つっつきボイス: 「スモークテストって耳慣れない用語だなー」「テストすら動かないような状況を避けるためのテストってことか」

開発作業でソースコードのちょっとした直し壊しやビルドの失敗に気付かず、動かないソフトウェアを次の工程に送っても差し戻されるだけで時間の無駄になる。こうした事態を避けるには、コンパイルやビルドした直後にそのソフトウェアが動くことを確認するのが効果的だ。これをスモークテストという。スモークテストは最低限のテストなので、「起動する」「基本機能が動作する」などを簡易に確認するだけでよいが、コンパイルやビルドするごとに行う必要がある。
情報システム用語事典 スモークテスト(すもーくてすと)より

ConvoxとRack: AWS上でHeroku的な環境を作れる

https://convox.com/より

convox/rackはHeroku的なPaaSをオープンソースでAWS上に構築できるようです。

つっつきボイス: 「そういえばHerokuってAWS上にあるのにAWSの機能やサービスをまったく受けられないんだよね」「Herokuよりもっと細かくカスタマイズしたい人向けなのかな?」「オンプレミスでもできるんだったら使いみちあるかも」


そこから少々脱線して、「Heroku」はどう発音するのかという話題になりました。

つっつきボイス: 「ヘロクって発音しているのをみると気になるなー: はーおーくーと発音して欲しい」「HerokuってHeroとHaikuを合わせたんだったっけ」「her oh kuu、って感じか」「英語圏の感覚だとherとokuで区切るかも」

Wikipedia: Herokuの意味によると、意味のある語にしたくなかったので造語にしたそうです。


そこからさらに、「課金」という言葉の使われ方についても話題になりました。

つっつきボイス: 「『課金する』っていう言葉も使い方がおかしいのをみかけますよ」「たしかに、『ユーザーが課金する』って既におかしい」「『ユーザーが課金される』ならいいけど」

参考: 「課金」の誤用が気になる

DeviseInvitableとRails API(RubyFlowより)

devise_invitable gemはDeviseにユーザーをメールでサイトに招待してパスワード設定までやってもらう機能を追加します。

つっつきボイス: 「これも自前でやった気がする」「こういうのがあるなら使うほうが楽かな」

securityheaders.io: セキュリティ関連のヘッダーをチェックできる

TechRacho記事「Railsアプリの認証システムをセキュアにする4つの方法」で知りました。もちろん悪用、いたずら厳禁。stagingサーバーあたりで使うぶんにはよいかもしれません。


https://securityheaders.io/より

つっつきボイス: 「Hall of Shameってのがいいなー」「Hall of Fameのダジャレですねw」「みんなHall of ShameのばっかりクリックしてるからRecentも真っ赤なFばっかりw」「これ日本だったら営業妨害呼ばわりされそうですね」

Quora: Bootstrap 4はいつになったらリリースされるんでしょうか?

つっつきボイス: 「いやほんとうに、いつになったら出るのか知りたいですよ」「もう出ないもんだと思ってますw」「5/24/2017の時点で92%だって」「コミットログは激しく更新されてるけど」


そこから、Bootstrapは3にしておけば十分という話題になりました。

つっつきボイス: 「Bootstrap 3と4の違いは小さいから、3にしとくのがいい」「2と3の変わりようはひどかったし」

LocalStack: AWSクラウド環境をローカルで動かしてテストとかに使える


https://github.com/atlassian/localstackより

AWS Summit 2017に参加したmorimorihogeさんが、@t_wadaさんの発表で注目したAtlassian製のツールです。

  • AWSのFake Objectを使える
  • AWSのサービスをlocalhostで起動できる
  • AWS接続のEndPointを変更するだけでよい(Mock/Stubは自前の実装が必要)
  • 特定言語に依存しない

といった特徴があるそうです。現時点では以下のサービスに対応しています。

  • API Gateway (http://localhost:4567)
  • Kinesis (http://localhost:4568)
  • DynamoDB (http://localhost:4569)
  • DynamoDB Streams (http://localhost:4570)
  • Elasticsearch (http://localhost:4571)
  • S3 (http://localhost:4572)
  • Firehose (http://localhost:4573)
  • Lambda (http://localhost:4574)
  • SNS (http://localhost:4575)
  • SQS (http://localhost:4576)
  • Redshift (http://localhost:4577)
  • ES (Elasticsearch Service)(http://localhost:4578)
  • SES (http://localhost:4579)
  • Route53 (http://localhost:4580)
  • CloudFormation (http://localhost:4581)
  • CloudWatch (http://localhost:4582)

morimorihoge: 「Managedなサービスのテストがやりやすくなる」「IAMもあればいいのに」

LivingStyleGuide: MarkdownとSass/SCSSで書けるフロントエンド向けスタイルガイド作成用gem(OpenRubyより)

フロントエンドだってスタイルガイドが欲しい、という方向け。カラーテーブルやフォント、コードなどもこうやって潤いのある感じに書けるようです。RailsやMiddlemanでも使えます。

バックエンド作業をやってるとつい後回しになってしまったりしますが、フロントエンドのスタイルガイドもちゃんと作りたいですね。

つっつきボイス: 「プログラマーが普通にMarkdownで書いただけだと見た目って残念になっちゃうよねw」「クライアントに見せるときにも使えそう」「どのぐらいまで自動でよしなにやってくれるのかな」「Railsのデモサイトがリンク切れっぽいなw」

Friends: 友だちとの活動をトラックできるgem(GitHub Trendingより)

友だちと会ったときの活動内容を入力して、後で頻度を集計したり次は誰と遊ぶかをおすすめしたりするCLIソフトウェアのようです。★500個超え、かつ熱心に更新されています。

$ friends suggest
Distant friend: Marie Curie
Moderate friend: Grace Hopper
Close friend: George Washington Carver

$ friends graph --with George
Nov 2017 |█∙∙|
Dec 2017 |∙∙|
Jan 2018 |█████∙∙|
Feb 2018 |███∙∙|

つっつきボイス: 「よーやるなーw」「このエネルギーはどこから来るんだろか?」

Gogs: Goで書かれたGitリポジトリ(GitHub Trendingより)

GitHubやGitLabのようなGitリポジトリソフトウェアです。星が2万個近くあります。

つっつきボイス: 「車輪を再発明したい人っているんだなーw」「Goでやりたいメリットって何だろう」「シングルバイナリだからデプロイが楽なんじゃ?」


今週は以上です。

関連記事

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

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

Rails公式ニュース

Ruby Weekly

OpenRuby

RubyFlow

160928_1638_XvIP4h

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の書いた記事

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ