- 開発
週刊Railsウォッチ(20170804)Rails 5.1.3と5.0.5が正式リリース、GitHubでローカライズ基盤サービス、正規表現で迷路を解くほか
こんにちは、hachi8833です。4年使ったMacbook Proのバッテリーがそろそろ天に召されそうです。
8月最初のウォッチ、行ってみましょう。
お知らせ: 来週は週刊Railsウォッチをお休みいたします。次回は8/18(金曜日)の予定です。
Rails 5.0.5と5.1.3が立て続けに正式リリース(Rails公式ニュースより)
月曜に先に5.0.5がリリースされ、今朝がた5.1.3もリリースされました。とりあえず5.1.3で記念写真↓。
Changelog
Rails: 今週の改修(Rails公式ニュースより)
修正: クエリに巨大な数値がある場合に結果が正しくなかった問題を修正
PRキリ番ゲットはkamipoさんでした。
# activerecord/test/cases/finder_test.rb より
+ def test_exists_with_large_number
+ assert_equal true, Topic.where(id: [1, 9223372036854775808]).exists?
+ assert_equal true, Topic.where(id: 1..9223372036854775808).exists?
+ assert_equal true, Topic.where(id: 1).or(Topic.where(id: 9223372036854775808)).exists?
+ assert_equal true, Topic.where.not(id: 9223372036854775808).exists?
+ end
つっつきボイス: 「DBMSの限界値をこんなふうに超えるケースは扱ったことなかったけど、挙動は確かにバグ」「idをすごい勢いで消費するシステムとかだと踏むかも: そういうシステムではid生成そのものがボトルネックになるので自前でid発番することが多そう」
「TwitterのSnowFlakeを思い出したでござる」
「id生成がボトルネックというのは?」「id生成はアトミックだから必ずロックがかかるでしょ」
そこからサーバー間の同期の話題になりました。
「システムによっては、複数サーバー間でデータ生成や順序処理を一意にするなどの目的で、サーバーごとに原子時計持たせることがある」「おー、サーバー間の同期や通信のコストを下げられるのか」
おまけ
2014年に製造された世界初の原子腕時計は、60万円投資すると10個限定でもらえるそうですが、あっというまにはけたそうです。手作り感溢れてます。
リファクタリング: Arelでbindのparamsを扱えるよう修正
かなり大規模にリファクタリングしてます。
# activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
def case_sensitive_comparison(table, attribute, column, value) # :nodoc:
- table[attribute].eq(value)
+ table[attribute].eq(Arel::Nodes::BindParam.new(value))
end
def case_insensitive_comparison(table, attribute, column, value) # :nodoc:
if can_perform_case_insensitive_comparison_for?(column)
- table[attribute].lower.eq(table.lower(value))
+ table[attribute].lower.eq(table.lower(Arel::Nodes::BindParam.new(value)))
else
- table[attribute].eq(value)
+ table[attribute].eq(Arel::Nodes::BindParam.new(value))
end
end
つっつきボイス: 「変更量ハンパない」「テスト通ればOKとはいっても、コアにこれだけ手を入れるってスゴイナー」
「ASTってやっぱり抽象構文木(abstruct syntax tree)か」「parserとかprepared statementのSQL生成部分とかの設計し直しまでやってるのかな」「記事数多いので次いきましょう」
ActiveSupport::Duration
の除算関連の変更
「除算の余り」と「除算」の2つのコミットをまとめました。moduloといえば数学用語の「剰余とか法」ですね。
- 新機能:
ActiveSupport::Duration
でmodulo操作をサポート
# activesupport/CHANGELOG.md より
# 変更前
5.minutes % 2.minutes #=> 60
# 変更後
5.minutes % 2.minutes #=> 1 minute
テストコードを見ると、分母と分子の単位(単位なしを含む)に応じて余りの単位をよしなに設定してくれるようです。
# activesupport/test/core_ext/duration_test.rb より抜粋
+ def test_modulo
+ assert_equal 1.minute, 5.minutes % 120
+ assert_equal 1.minute, 5.minutes % 2.minutes
+ assert_equal 1.minute, 5.minutes % 120.seconds
+ assert_equal 5.minutes, 5.minutes % 1.hour
+ assert_equal 1.day, 36.days % 604800
+ assert_equal 1.day, 36.days % 7.days
+ assert_equal 800.seconds, 8000 % 1.hour
+ assert_equal 1.month, 13.months % 1.year
end
ActiveSupport::Duration
で除算が常にNumeric
を返すよう修正
# activesupport/test/core_ext/duration_test.rb より
+ def test_division
+ assert_equal 1.hour, 1.day / 24
+ assert_instance_of ActiveSupport::Duration, 1.day / 24
+
+ assert_equal 24, 86400 / 1.hour
+ assert_kind_of Integer, 86400 / 1.hour
+
+ assert_equal 24, 1.day / 1.hour
+ assert_kind_of Integer, 1.day / 1.hour
+ end
つっつきボイス: 「(1つ目のa54e13を見ながら)ええー、分で分を割ったら単位がキャンセルされると思ってたけど、余りって単位を付けていいものなの?」「数学科出身のkazzさん、いかがでしょうw」「数学だと単位ってそもそもほとんど俎上に載らないんですよ」「むしろ物理学の方が単位にうるさいかも」「でも物理だと余りを出さないですね」「代わりに精度重視: 除算は最後に回すとか」
「単位付きの余りは少しぎょっとするけどこれはこれで便利そうだし、原理上そんなにおかしいものでもなさそうですね」
「Duration
って、ActiveSupportに限らず考えないといけないことが多くて大変ー」
- 参考: TechRacho: ActiveSupport::Duration関連記事
Ruby-trunkより
バグ: 継承されたメソッドでRefinementのスコープが無視される
module Test
refine String do
def sleep; end
end
end
puts "start"
"".sleep 3
puts "end"
つっつきボイス: 「RailsだとRefinementってまず見かけないけどねw」「Refinementって志高いし実装もすごく大変だったらしいのに、まだそれほど使われてない気がしました」
activerecord-import: ActiveRecordでデータを一括読込するgem(Random Rubyより)
- 元記事: A better way to import all your records using ActiveRecord Import!
- リポジトリ: zdennis/activerecord-import
★2000に迫る勢いです。
# https://github.com/zdennis/activerecord-import/wiki/Examples#import-using-columns-and-arrays より
columns = [ :title, :author ]
values = [ ['Book1', 'FooManChu'], ['Book2', 'Bob Jones'] ]
# Importing without model validations
Book.import columns, values, :validate => false
# Import with model validations
Book.import columns, values, :validate => true
# when not specified :validate defaults to true
Book.import columns, values
つっつきボイス: 「以前のウォッチでも少し話したけど、activerecord-importは昔からある定番gemですね: 案件でも使ったことあるし、CSVインポート10000件とかは余裕」「要するにvalidationかけてからINSERT
複文でINSERT
を実行するヤツ」
「いい点はRailsのvalidationがかかるので割りと自然な使い方ができる」
「悪い点があるとすれば、Rubyコードである以上カリカリに速くはならないことか: 案件でも速度を出すために結局生SQL書いたこともあったし」
jb gemでRailsのJSONを高速にしたった(RubyFlowより)
gemは★500に迫る勢いです。関係ありませんが、最近medium.comの技術ブログを見かけることが妙に増えました。
つっつきボイス: 「jbって知らなかったけど、amatsudaさんのgemか」「新しいgemですね」
「うん、Rails標準のJBuilderよりこっちの方が自然に書けそう: JBuilderのインターフェースはあまり直感的でないところがあって、書き足していくうちにだんだん居心地が悪くなってきたり」
「jbでよくないのは名前ぐらいかなw」「こんなに短いとねー」
ちょうど対照的なコードサンプルがあったので貼ってみました。
# jbの場合(https://github.com/amatsuda/jb)
json = {
content: format_content(@message.content),
created_at: @message.created_at,
updated_at: @message.updated_at,
author: {
name: @message.creator.name.familiar,
email_address: @message.creator.email_address_with_name,
url: url_for(@message.creator, format: :json)
}
}
if current_user.admin?
json[:visitors] = calculate_visitors(@message)
end
json
# JBuilderの場合(https://github.com/rails/jbuilder)
json.content format_content(@message.content)
json.(@message, :created_at, :updated_at)
json.author do
json.name @message.creator.name.familiar
json.email_address @message.creator.email_address_with_name
json.url url_for(@message.creator, format: :json)
end
if current_user.admin?
json.visitors calculate_visitors(@message)
end
大文字でJBといえば:
Errbit: AirBrake API準拠のエラーログ収集gem
- リポジトリ: errbit/errbit
BPSでも標準的に使われています。
つっつきボイス: 「Errbitシラナカッター」「シラナカッター」「マジでw TechRachoにもErrbitの記事ありますよ↓」「その頃ワタイらBPSにおりませんでした」
「タイトルにもあるようにAirBrakeのAPIと互換性あって、AirBrakeのgemをそのまま使うし:
置き場所がAirBrakeじゃないだけ」
「Rails以外にも使えるし、↑上の図でもわかるようにエラーをとりあえずグループ分けしてくれるところとかありがたい: 細かくは他の方法で見たりもするけど」
「結果をSlackに流しておくとさらに便利ですヨ~」
「以前はAirBrakeが定番だったけど、有料化したとたんにみんなすごい勢いでalternative探してErrbitが浮上してきた」
参考
Trailblazer: Rails MVCのビジネスロジックを分離するgemスイート
- 公式: trailblazer.to
- リポジトリ: trailblazer/trailblazer
JSON HALを調べていてTrailblazerにたどり着きました。Trailblazerについては昨年のRailsウォッチでごく簡単に触れたことがあり、★も多いのですが、日本語での情報をほとんど見かけないので、今回少しだけ一同で眺めてみました。
# http://trailblazer.to/gems/operation/2.0/index.html より
class Song::Create < Trailblazer::Operation
extend Contract::DSL
contract do
property :title
validates :title, presence: true
end
step Model( Song, :new )
step :assign_current_user!
step Contract::Build()
step Contract::Validate( )
failure :log_error!
step Contract::Persist( )
def log_error!(options)
# ..
end
def assign_current_user!(options)
options["model"].created_by =
options["current_user"]
end
end
つっつきボイス: 「へーなるほど、コントローラの制御ロジックをstep
でOperation
に切り出したり↑」「Contract
でステートを記述したり↓」「SalesForceみたいに、大きなビジネスロジックを扱うアプリを開発するための基盤という感じ」「日本のSIer的な開発スタイルに向いているのかも」「昨今はどっちかというとマイクロサービスアーキテクチャ指向なんで、今後流行るのかなあ、どうなんだろう」
# app/concepts/song/contract/create.rb
module Song::Contract
class Create < Reform::Form
property :title
property :length
validates :title, length: 2..33
validates :length, numericality: true
end
end
trailblazer n. 先駆者, 草分け.
オピニオン: gemを追加する前にもうちょっと考えよう
短いながらも良記事です。
つっつきボイス: 「『車輪の再発明を避けようとしてgemだらけになる』ことのデメリットについて触れてるのがいい」「あまりにトリビアな機能を追加するgemとか『それ、書いた方が早くね?』って思うこと多いし」「たとえばどんなgemでしょうか?」「acts-as-taggable-onとかw」
compartmentalization: {名} : 区画化、区分化、区分け、棲み分け
米国Kite社がオープンソースツールに広告を仕込んで非難轟々
先の「We need better compartmentalization」の記事中のリンクで知りました。
仕込まれたとされるのはATOMエディタのプラグインであるMinimapとautocomplete-pythonだそうです。
CIとCD(Continuous Deployment)とCD(Continuous Delivery)の違い(RubyFlowより)
- 元記事: What's the Difference Between Continuous Integration, Continuous Deployment and Continuous Delivery?
semaphoreci.comより
つっつきボイス: 「この図↑が( ・∀・)イイ!!」「Continuous DeliveryとContinuous Deploymentの違いがひと目でわかりますね」
「CDとCDって、略語が完全一致しているのが向こうの人にとっても残念だろうな」「まあよくあることだし」
OWASPチートシートでRailsのセキュリティ問題を防止(Random Rubyより)
記事は普通な感じですが、OWASPの方が話題になりました。
つっつきボイス: 「OWASPは強制力こそ持たないけど、セキュリティ関係のガイドラインとかチェックシート的などを提案・啓蒙している団体ですね」「大手企業が実施するセキュリティチェックの品質監査ガイドラインなんかでもOWASPを参照していることがあったりするので、覚えておくとよいです」
「少なくともIPAよりは信頼されてるw」
Elixirを学んだらRubyが上達したお(Ruby Weeklyより)
Elixirの特徴に触れることでRubyのコーディングに好影響があったという割りと短い記事です。
# https://www.amberbit.com/blog/2017/7/27/how-learning-elixir-made-me-better-ruby-developer/ より
class Counter
attr_reader :value
def initialize(payload)
@value = payload.to_i
end
def increment
Counter.new(@value + 1)
end
end
SOLIDの「D」: 依存関係逆転法則(Ruby Weeklyより)
SOLIDの連載シリーズです。他の記事も読み応えありそうです。
つっつきボイス: 「この図も、独特だけど見せ方が面白い」「六角形ぇェ」「SOLIDってDDD(ドメイン駆動開発)関連の記事で見たことがあったような」
RubyをJavaScriptっぽくする(Ruby Weeklyより)
これでもRubyです:
var first = 3;
var second = 4;
var sum = function(a, b) {
a + b;
}
console.log("Sum = ", sum(first, second));
つっつきボイス: 「(´д`)イヤァ-ン!!ww」「これはひどずw」「しかも古いJavaScriptでw」
Railsで時間を変えてテストする方法(RubyFlowより)
つっつきボイス: 「タイトルでtimecop使ってるの丸わかりw」「テストで時間を変えるのってタイムトラベルって呼ぶんですね」「タイムトラベルらしく、timecopは時間を移動する他に元の時間に戻ったりもしますよ」
Passenger 5.1.7リリース(RubyFlowより)
前回のメジャーアップデートでのChangelogが多すぎて追いきれませんでした。
Passenger Libraryというサポートサイトがやたら充実しています。
Cooper Pressの技術情報ニュースレター
英語圏の技術情報サイトが過剰気味な中、Cooper Pressのニュースレターは編集が効いていて選別が割りとよい感じです。いくつかはWeb上で直接読めるものもあり、ニュースレターのみのものも最新版ならWeb上で読めます。RailsウォッチでもRuby Weeklyをよく参照しています。
- Javascript Weekly -- サイトでも読める
- Frontend Focus -- ニュースレターのみ
- Ruby Weekly -- サイトでも読める
- node weekly -- サイトでも読める
- React Status -- ニュースレターのみ
- DB Weekly -- ニュースレターのみ
- Web Operations Weekly -- ニュースレターのみ
- Serverless Status -- ニュースレターのみ
- Mobile Web Weekly -- ニュースレターのみ
- Golang Weekly -- ニュースレターのみ
- Postgres Weekly -- ニュースレターのみ
みなドメインが違うので最初気づきませんでしたが、レイアウトが共通なので同じところで発行されていることがわかります。
Cocoon: jQueryで動的なフォームのネストをやりやすくするgem
- リポジトリ: nathanvda/cocoon
Driftingruby.comのNested Forms with Cocoonで見つけました。★2400です。
つっつきボイス: 「管理画面みたいにUIの制約が少ない案件だとちょっと便利だったりするかな」「案件で添付ファイル機能とか要求されなければいけるかも」
オピニオン: あらゆる言語を学べ(Random Rubyより)
- 元記事: Learn every language
真ん中あたりで「早いうちにC言語をやっとけ」「アセンブラもやっとけ」と書いてあったのが目に止まりました。
- 自分にレッテルを貼るのをやめる(私はRails開発者です、など)
- メタなことをやる
- 他の言語の元となる言語(archetypal languages)をやる
- ひたすら書く
つっつきボイス: 「ひと目でbrainf*ckとわかる↑」「視覚的な知名度ハンパないw」「Array programmingってなんだろ?」「つ ↓」
Rubyで機械学習: k-meanクラスタリング(RubyFlowより)
The Last API Wrapper: Web APIのラッパー作成用gem(RubyFlowより)
★はまだ100個に到達していません。
つっつきボイス: 「grapeというものが前からあるよん↓」
Southeast Ruby Conference: 米国ナッシュヴィルで10月に開催(RubyFlowより)
- 公式サイト: Southeast Ruby Conference
テネシー州ナッシュヴィルでの開催というのがちょっと珍しく感じたので取り上げてみました。
GitLocalize: GitHubベースのローカライズ基盤サービス
- サイト: GitLocalize
- 概要: What is GitLocalize
https://github.com/marketplace/gitlocalizeより
つい先ほど知りました。GitHub自ら始めたサービスかと思いきや、よく見るとmarketplaceなのでサードパーティでした。
まだ詳しくみていませんが、GitHubと統一的に使えるらしい点がインパクトありそうです。
もしかしたらですが、ローカライズ業界に変化が訪れる予感がうっすらとしています。
Nginxのセキュリティ対策ベスト25
2010年と新しくはありませんが、そこそこまとまってるように見えたので。
つっつきボイス: 「早々に『SELinuxをオンにしろ』とか時代を感じる」「量は多いけど、ふつううううううううううううのことしか書いてないな、さすがにw」
そこから、Apacheの違いやSELinuxについて話題になりました。
「Apacheはhttpd.confでまとめて扱えるから楽といえばとても楽: その代わりそれがセキュリティ上の弱点にもなる」
「Nginxは一か所にまとまってないし、自力で設定する気になれないような設定ファイルもある」
「SELinuxは確かに固いけど、固すぎて不自由さがハンパない」
遅いと思っていたWEBRickが...
What happened when I compared the "slowest" server in Ruby to NGINX? The results surprised even me https://t.co/kGjLc8ZbBV
— Richard Schneeman (@schneems) 2017年8月1日
各所でバズっている記事です。
gosu: Ruby向け2Dゲーム開発ライブラリ(Awesome Rubyより)
- サイト: www.libgosu.org
- リポジトリ: gosu/gosu
CSS(Frontend Weeklyより)
CSS-Tricks: Shadow DOMで遊んでみたお
<iframe>
タグの進化版ともいえるShadow DOMでTwitterのツイートを埋め込んでみつつ、Shadow DOMを解説しています。
CSSは90年代後半以来複雑になったか
npmjs.comでマルウェアが大量に発見される
これも各所で話題になっています。
Chrome 60 が正式リリース
7月末にChrome 60がアップデートされました。私も本記事を書きながらアップデートしたら思ったより時間がかかってしまい、ハマりました。
BPS社内では新機能のAudit Panelが話題になりました。
私はV8の正規表現の強化(Unicodeプロパティの扱いとか)が今後予定されている方に個人的に盛り上がってしまいました。
/\p{Number}/u.test('①'); // true
/\p{Alphabetic}/u.test('雪'); // true
正規表現で迷路解いたりしてみた
こういう遊び好きです。
Go言語ベースやってますが、この記事で使っているdlclark/regexp2というパッケージは実は.NET Frameworkの正規表現ライブラリをGoに移植したもので、Goの標準正規表現ライブラリよりずっと強力であり、実は私もこっそり愛用してたりします。
// https://github.com/dlclark/regexp2 より
if m, _ := re.FindStringMatch(`Something to match`); m != nil {
// the whole match is always group 0
fmt.Printf("Group 0: %v\n", m.String())
// you can get all the groups too
gps := m.Groups()
// a group can be captured multiple times, so each cap is separately addressable
fmt.Printf("Group 1, first capture", gps[1].Captures[0].String())
fmt.Printf("Group 1, second capture", gps[1].Captures[1].String())
}
番外
JSONで取れるデータあらいざらい(GitHub Trendingより)
- リポジトリ: toddmotto/public-apis
最初opendatajson/football.jsonにしようかと思いましたが、こっちの方が断然すごかったので。
音楽、ゲーム、映画、アニメ、金融、詐欺チェック、チャック・ノリスねた、Tumblr、飛行履歴、天気など、よくぞこれだけ集めたと思います。
TypeScriptの型システムはチューリング完全
// 止まらない再帰
type Foo<T extends "true", B> = { "true": Foo<T, Foo<T, B>> }[T];
let f: Foo<"true", {}> = null!;
GitHub Issueでこれだけボタンが押されているのを自分は初めて見ました。
SNSはボキャブラリーの発達に好影響?ロシアの研究
最初に見たのは日本語記事「SNSばかりやっているとバカになる? ロシアの研究で意外な発見」でしたが、途中から有料のうえ、元記事の英語なら全文読めました。
香港のAIチャットが党を批判してサービス停止
各所で話題になっていますが、ソースは今のところこれ以外に見当たりません。QQ wheatgrass was banned, we talk about the chat robot "crime" Historyは、それを受けた評論記事です。
今週は以上です。
バックナンバー(2017年度)
- 週刊Railsウォッチ(20170623)gemを見極める7つのコツ、mixinがよくない理由、重いページをrender_asyncで軽減ほか
- 週刊Railsウォッチ(20170616)railsdiff.orgはアップグレードに便利、RubyのDSLとかっこの省略、TerraformをRubyで制御ほか
- 週刊Railsウォッチ(20170609)ついにtherubyracerからmini_racerへ、注意しないとハマるgem、5.1でのVue.jsとTurbolinksの共存ほか
- 週刊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など)です。