- 開発
週刊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関連の英語記事やサンプルをメモします。
- Vue.jsでRailsのフォームのネストをパワーアップ
- Vue.jsでRailsのフォームのネストをパワーアップ(Part 2)
- Vue.jsとRailsを使ってみる
- リポジトリ: rlafranchi/vuejs-rails-example
気をつけないとハマるかもしれないgem 5+1種(RubyFlowより)
先週のウォッチで紹介した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っぽく同期してみたお
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より)
starting day 3 of #railsconf strong with a keynote by @polotek: "how it feels to be black in tech" --thank you for sharing your stories pic.twitter.com/rrDUTnaHrB
— savannah🏳️🌈 (@Savannahdworth) 2017年4月27日
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フレームワークです。メガネのタヌキみたいなのがマスコットです。
この記事では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的な環境を作れる
- サイト: convox.com
- リポジトリ: convox/rack
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サーバーあたりで使うぶんにはよいかもしれません。
つっつきボイス: 「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クラウド環境をローカルで動かしてテストとかに使える
- リポジトリ: atlassian/localstack (ただしメインはBitbucketにある)
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より)
- リポジトリ: JacobEvelyn/friends
友だちと会ったときの活動内容を入力して、後で頻度を集計したり次は誰と遊ぶかをおすすめしたりする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より)
- リポジトリ: gogits/gogs
GitHubやGitLabのようなGitリポジトリソフトウェアです。星が2万個近くあります。
つっつきボイス: 「車輪を再発明したい人っているんだなーw」「Goでやりたいメリットって何だろう」「シングルバイナリだからデプロイが楽なんじゃ?」
今週は以上です。
関連記事
- 週刊Railsウォッチ(20170602)チームが喜ぶ19のgem、Bundler 1.15が高速化&機能追加、Deviseに挑戦する新認証gem「Rodauth」ほか
- 週刊Railsウォッチ(20170512)Rubyの不思議な挙動「シャドウイング」、コードレビュー作法を定めるDanger gemほか
- 週刊Railsウォッチ(20170428)Rails 6.xでの’#form_for’と
#form_tag
廃止決定のその後、deviseの5.1対応はこれから、ほか - 週刊Railsウォッチ(20170421)RailsConfが来週アリゾナで開催、コントローラを宣言的に書けるdecent_exposure gemほか
- 週刊Railsウォッチ(20170414)サーバーを危うくする1行のコード、PostgreSQL 10の新機能ほか
- 週刊Railsウォッチ(20170407)N+1問題解決のトレードオフ、Capybaraのテスト効率を上げる5つのコツほか
- 週刊Railsウォッチ(20170331)PostgreSQLの制約機能を使えるRein gemはビューも使えるほか
- 週刊Railsウォッチ(20170324)Ruby 2.4.1リリース、GAEがついにRubyに対応、このgemがないと生きていけない27選ほか
- 週刊Railsウォッチ(20170317)Railsパフォーマンスチューニング本、DBレコード存在チェックの最速メソッド、RubyのUnicode正規化ほか
- 週刊Railsウォッチ(20170310)クールなDocker監視ツールCtop、RailsがGoogle Summer of Code 2017に正式参加、Unicode 10.0.0ドラフト発表ほか
- 週刊Railsウォッチ(20170303)5.0.2正式リリース、メタプログラミングに懲りた話、bundler 1.12のバグ、すぐ試せるWebアノテーションほか
- 週刊Railsウォッチ(20170227)Rails 4.2.8リリース、SHA-1コリジョンアタック、便利なハッシュ変換ツールほか
- 週刊Railsウォッチ(20170217)Rails 4.2.8.rc2リリース、Ruby 2.4正規表現とActiveSupportのnormalizeほか
- 週刊Railsウォッチ(20170210)JRubyやRubiniusの配列への追加はスレッドセーフではないほか
- 週刊Railsウォッチ(20170203)AnyLogin gemで開発中に楽々再ログイン、イベント数ベース課金の監視サービスRollbarほか
- 週刊Railsウォッチ(20170127)わかりやすいAWSサービス名、Rails DBは便利、TruffleRubyの驚異的速度ほか
- 週刊Railsウォッチ(20170120)Ruby 2.5.0 devリリース、古いMySQLのサポート終了、uniqメソッドが削除ほか
- 週刊Railsウォッチ(20170116)Ruby 2.4の詳細、範囲指定したsumメソッドは速い、rescueの挙動を動的に変更ほか
- 週刊Railsウォッチ(20170110)ReactをRailsに置き換える、Ruby 2.4の新機能ほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやRSSなど)です。