- Ruby / Rails関連
週刊Railsウォッチ(20180925)Rails大規模支払サービス開発のノウハウ、RailsのMySQLがutf8mb4に移行、Rpush gemほか
こんにちは、hachi8833です。Linusが京都に隠遁し、RubyがGitへの移行を検討し、GuidoがPythonの意思決定から降りた今日この頃、皆さまいかがお過ごしでしょうか。私は先日自宅のAirMac TimeCapsuleが息を引き取りました。
Linus「カーネルメンテナ一旦降りるわ」
Matz「gitに切り替えようかな」
Guido「pythonメンテナ辞めるわ」
お気持ち連発しすぎだ。ジャックマーやマスクもだし、我々の知らないところで隕石が地球に衝突する情報が出回ってるのではと疑うレベル #藤子F脳— 最速配信研究会山崎大輔 制約理論及び待ち行列理論による技術経営コンサルとエンジニア起業相談やってます (@yamaz) September 17, 2018
- 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
- 「つっつきボイス」はRailsウォッチ公開前ドラフトを社内有志でつっついたときの会話です👄
9/25は予定を変えてウォッチを公開いたします🙇。
つっつきボイス:「AirMac、いつもチンチンに熱くなってた🍜ので熱死したっぽいです😭」「AirMacシリーズ自体がディスコンになっちゃいましたからね〜⛔」
「そうそう、RubyのリポジトリをGitHubに移行する話」「大江戸Ruby会議07でもちらっと話に出てました」「Subversionから移りたくない人もいるだろうし、時間はかかりそうですね」「GitのWindows対応が残念すぎるから移りたくないという理由を挙げていたのを以前どこかで見かけました」「それはある😅」「Rubyほどの規模ならSubversionでもいいのかなと思ったりもするけど、もしかするとGitそのものというよりGitHubの機能を使いたいからだったりして?🤔なんてね😆」「😆」
後で探すと、リポジトリは今年の3月からできているようです↓。
参考: git.ruby-lang.org を作った - HsbtDiary(2018-03-24)
参考: Feature #11741: Migrate Ruby to Git from Subversion - Ruby trunk - Ruby Issue Tracking System
訂正(2018/09/26)
直接フィードバックをいただきました。訂正いたします🙇。
Rubyは近い将来にはGitHubに移行しません。Gitに移行するだけです。もっともGitに移行したらGitHubとの双方向同期は簡単ですね。
Link: 週刊Railsウォッチ(20180925)Rails大規模支払サービス開発のノウハウ、RailsのMySQLがutf8mb4に移行、Rpush gemほか: https://t.co/tmxvPyIUdL
— Yukihiro Matz (@yukihiro_matz) September 26, 2018
⚓【お知らせ】週刊Railsウォッチ「公開つっつき会」#3開催
ご好評にお応えして「週刊Railsウォッチ 公開つっつき会 第3回」を10月4日(木)19:30〜より開催いたします。詳しくは上のリンクをどうぞ。ノートPC片手にお気軽にご応募ください🙇🙇。
⚓Rails: 先週の改修(Rails公式ニュースより)
先週のウォッチで公式の更新情報をいくつか先回りできたのがちょっとうれしいです😊。
⚓digest pathをループから切り出してオブジェクト割り当てを削減
# actionview/lib/action_view/helpers/cache_helper.rb#L#211
- def cache_fragment_name(name = {}, skip_digest: nil, virtual_path: nil)
+ def cache_fragment_name(name = {}, skip_digest: nil, virtual_path: nil, digest_path: nil)
if skip_digest
name
else
- fragment_name_with_digest(name, virtual_path)
+ fragment_name_with_digest(name, virtual_path, digest_path)
+ end
+ end
+ def digest_path_from_virtual(virtual_path) # :nodoc:
+ digest = Digestor.digest(name: virtual_path, finder: lookup_context, dependencies: view_cache_dependencies)
+ if digest.present?
+ "#{virtual_path}:#{digest}"
+ else
+ virtual_path
end
end
つっつきボイス:「局所最適化っぽい改修かな」「毎回計算して引っ張ってくるのをやめて、一度使ったものを使い回す形にする、よくある形の修正」「いわゆるメモ化ですね😃」
# actionview/lib/action_view/renderer/partial_renderer/collection_caching.rb#L47
+ def digest_path
+ @digest_path ||= @view.digest_path_from_virtual(@template.virtual_path)
+ end
⚓MySQLのデフォルト文字コードセットがついにutf8mb4
に
# activerecord/Rakefile#L
desc "Build the MySQL test databases"
task :build do
config = ARTest.config["connections"]["mysql2"]
%x( mysql --user=#{config["arunit"]["username"]} --password=#{config["arunit"]["password"]} -e "create DATABASE #{config["arunit"]["database"]} DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci ")
%x( mysql --user=#{config["arunit2"]["username"]} --password=#{config["arunit2"]["password"]} -e "create DATABASE #{config["arunit2"]["database"]} DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci ")
%x( mysql --user=#{config["arunit"]["username"]} --password=#{config["arunit"]["password"]} -e "create DATABASE #{config["arunit"]["database"]} DEFAULT CHARACTER SET utf8mb4" )
%x( mysql --user=#{config["arunit2"]["username"]} --password=#{config["arunit2"]["password"]} -e "create DATABASE #{config["arunit2"]["database"]} DEFAULT CHARACTER SET utf8mb4" )
end
つっつきボイス:「お、とうとう来た㊗️」「もっと早くに移行してもよさそうなのに、まだだったんですね」「そうそう、かなり大きなbreaking changesなのでずっと見送られてた⚾️」「マイグレーションが避けられないから?」「いや、database_ymlができてればそこにはエンコーディングが書かれているものなのでそっちは問題ない」「別の問題なんですね」「実はMySQLでutf8mb4
を安心して使えるようになったのはMySQL 5.7からの話で、5.6.xだとその下のマイナーバージョンによってはインデックス周辺で追加の操作が必要になったりするので、マイナーバージョンに気をつけておかないとutf8mb4
でたまにハマることがある」「お〜😲」「5.7以降ならマイナーバージョンを気にせず使える😋: たぶんそういうのもあってutf8mb4
への移行に踏み切ったんでしょうね」
「おや、#33608の修正だとcollation(照合順序)が修正されてないっぽい?collationがutf8mb4_unicode_ci
だと例の寿司ビール問題↑が発生しちゃうので」「コードレビューでもツッコミ入ってますね」「たぶんこの後のコミットでcollationも対応するだろうし: collationも大事だから」
こんなつぶやきも見つけました↓☺️。
おそらくこれに関連して、以下のコミットでMySQL 5.1がutf8mb4
文字セット非対などの理由でついにサポート終了しました🙋🏻♂️。
⚓#inspect
でもカラムフィルタが効くようになった
つっつきボイス:「これは先週扱った180dcd1の続きのPRとしてドキュメントも追加されていました」「例のfilter_attributes
ですね😃」
⚓ActiveStorageのルーティングパス/rails/active_storage
をカスタマイズ可能に
routes_prefix
属性が追加されて/files/blobs/:signed_id/*filename
などのパスを使えるようになりました。
# activestorage/lib/active_storage.rb#L35
module ActiveStorage
extend ActiveSupport::Autoload
...
+ mattr_accessor :routes_prefix, default: "/rails/active_storage"
つっつきボイス:「今までは固定だったんですね」「従来はget "/rails/active_storage/blobs/:signed_id/*filename"
ってなってたし」「思い切りハードコードされてた」「こんなのがまだ残ってたんだな〜: Rails使っているのを見せたくないことも多いだろうし」
⚓ActionCableの接続でname
にRedisのidを含むようになった
- PR: ActionCable: add id option to redis adapter config by got2be · Pull Request #33798 · rails/rails
# 修正前
$ redis-cli client list
id=669 addr=127.0.0.1:46442 fd=8 name= age=18 ...
# 修正後
$ redis-cli client list
id=673 addr=127.0.0.1:46516 fd=8 name=ActionCable-PID-19413 age=2 ...
# actioncable/lib/action_cable/subscription_adapter/redis.rb#L16
cattr_accessor :redis_connector, default: ->(config) do
- ::Redis.new(config.slice(:url, :host, :port, :db, :password))
+ config[:id] ||= "ActionCable-PID-#{$$}"
+ ::Redis.new(config.slice(:url, :host, :port, :db, :password, :id))
end
つっつきボイス:「前はname=
が空だったんですね」「バグかな?っと思ったけど今まではRedisにつなぐときにname=
を指定してなかったのか: これでRedis接続を名前で区別できるようになったと」「$$
って何だろうと思ったらプロセスidが取れるRubyの特殊変数でした↓」「そうそうこれ」「この記事書いといてよかったと思った瞬間😋」
⚓レコードが実際にsaveされるまでカウンタキャッシュが更新されないようになった
これはコミットログから見積もった最新の修正です(つっつき会時点)。過去のさまざまな改修を経て、仕上げとして@_after_replace_counter_called
ガード条件を削除したとのことです。長患いを経て包帯が取れた感じですね✨。
# activerecord/lib/active_record/associations/belongs_to_association.rb#L50
def replace(record)
if record
raise_on_type_mismatch!(record)
- update_counters_on_replace(record)
set_inverse_instance(record)
@updated = true
- else
- decrement_counters
end
replace_keys(record)
self.target = record
end
...
- def update_counters_on_replace(record)
- if require_counter_update? && different_target?(record)
- owner.instance_variable_set :@_after_replace_counter_called, true
- record.increment!(reflection.counter_cache_column, touch: reflection.options[:touch])
- decrement_counters
- end
- end
- # Checks whether record is different to the current target, without loading it
- def different_target?(record)
- record._read_attribute(primary_key(record)) != owner._read_attribute(reflection.foreign_key)
- end
つっつきボイス:「kamipoさん4度目の正直!」「あぁ〜カウンタキャッシュは結構大変なんですよね〜: トランザクションと絡んでくると特に」「お〜😲」「カウンタキャッシュってアプリケーション層でやろうとするとどうしても大変で、本来ならDBMS側でtrigger関数なんかを設定してやる方がきれいに書けるし、速い💪」「トランザクションも?」「確実にトランザクショナルになるので安全🏥」「アプリ層だとトランザクションと一致しなくなったりすることがあるのか」「とは言っても、アプリ層だとlambdaでコードを渡せるとか便利な点もいろいろあります」「単なるカウンタキャッシュが欲しいだけならデータベースにトリガを追加する方が軽くて速い: よほど下手なやり方をしなければですが」
⚓Rails
⚓元Airbnb/PayPal開発者が語る大規模Rails支払システム構築のノウハウ
Link: Large Scale Payments Systems and Ruby on Rails – Airbnb Engineering & Data Science – Medium: https://t.co/nlz8gwUCaB
— Yukihiro Matz (@yukihiro_matz) September 18, 2018
つっつきボイス:「そういえばAirbnbのサイトもRailsですね」「転職活動用の職歴アピール記事かなとも思いましたが」「テスタビリティにaudit trail(監査用の追跡記録)とか、支払サービスの構築でやりそうなことはひととおり押さえてそう」
「ActiveRecordの上に置くProtectedAccessって何でしょう?」「これはいわゆるエンタープライズアプリケーションアーキテクチャなんかでよくある、上に層を1つ重ねるものじゃないかな: ActiveRecordを生で扱うにはシステムが大きすぎるときなんかにこういう設計にすることがあります」「お〜😲」
「うん、続きに書いてある↓: 既存レコードは更新せずに必ずINSERTだけで記録すると」「あー、監査ではデータが消えちゃまずいからこういうふうにしそうですね: こんなgemがあった気がしたけど何だっけ...(PaperTrailでした)」「全記録を残すという目的以外に、INSERTのみで記録すると再インデックスが一切不要になるストレージ層のフラグメンテーションを回避できるというメリットもあります: 既存レコードを更新するとデータベースを再インデックス(VACUUMとか)が必要になるので(追記: 最近のPostgreSQLはvacuum不要です)」「あ〜そっか!😃」「大規模なデータベースなんかでよく使われる戦略です🗻」
一方
ProtectedAccess
は境界面で(モデル同士を)隔離しつつ、amount=
やsave
やActiveRecordモデルを使える。save
が呼ばれると、既存のレコードを更新するのではなく新しいレコードを作成して保存する。Payment
テーブルにアクセスできる実際のモデルを呼び出すことはできないようになっている(class Payment < ProtectedAccess
オブジェクトのprivateメンバー以外何もないため)。
同記事より大意
「記事の続きはというと、バリデーションは厳し目にしてなるべく手前の方で問題を検出するようにする: これは正しい戦略📊」「『Fail Fast (and loud!)』だから早期発見周知徹底的な」「あとはService Objectを使う話↓: コードは冗長になるけど、この規模になるとこういう形でやることになるでしょうね☺️」
# 同記事より
class CompleteTransaction < ServiceBase
def initialize(opts = {})
validate(opts)
@txn = opts[:txn]
@buyer = opts[:buyer]
@status = opts[:status]
end
def validate(opts)
# use parameter validation to strongly check expected parameter values
end
def perform
response = Net::HTTP.post_form....
# inspect response and return accordingly
end
end
「Complexity Filters?」「これはRubocopの設定にあるABCコードサイズという評価基準」「なるほどそっちですか」「開発人数が増えてくるとこうやってABCスコアを減らすことも必要になるだろうな(つらいけど😆)」
- Assignment(代入)
- Branch(呼び出し)
- Condition(条件文)
参考: RuboCopのABC Sizeチェックについて調べた - 毒シューマイ
「Disable replica readsは、決済系の処理はレプリカデータベースから読み込まないようにする: そりゃそうだ😎」
「全体にバランスのいい記事!😍」「俺はエンタープライズアプリ書けるぜ!というアピールとしてもいい感じ💪」
追記:
参考: SQLite Query Language: VACUUM
⚓JSON Web Token(JWT)とRailsのcookie store
つっつきボイス:「はてブに上がってたヤツです」「あ〜これこれ😆😆: まだ最後まで読んでないけどっ」「文中でRailsのcookie storeもJWTと同じような問題を抱えてるとあったので」「Railsのcookie storeもいろいろつらみがあるし、自分もJWTをセッションに使うのはあまりやりたくない😔」「『JWTはステートがない』って書かれてますね」「JWT自体はピュアなAPIインターフェイスみたいなものなので、ステート管理の機能はないはず」
「『鍵管理』問題、あるある」「『退職者問題』って、以前もウォッチで話題になったマスターキーの保存場所の話にも通じる感じですね」「ちなみにJWTはAPIでは割とメジャーな方式です☺️」
⚓Rpush: Railsでも使えるRubyプッシュ通知gem(Ruby Weeklyより)
つっつきボイス:「FireBaseなどをプッシュのバックエンドに使うRubyのインターフェイスという感じですね: 他にもこういうのがバックエンドに使えるのか↓」「Windows Phone!使う人いるのかな〜😆」「😆」
- Apple Push Notification Service(Safari Push Notificationsも含む)
- Firebase Cloud Messaging(旧Google Cloud Messaging)
- Amazon Device Messaging
- Windows Phone Push Notification Service
- Pushy
「頑張って個別のサービスのコードを書かなくてもこうやってRubyらしいインターフェイスでプッシュ通知を書けるというのは中々いいかも😋」「😍」「とりあえず★押しとこ👉」
# 同リポジトリより
app = Rpush::Adm::App.new
app.name = "kindle_app"
app.client_id = "..."
app.client_secret = "..."
app.connections = 1
app.save!
「そういえば社内勉強会でも、サーバーからのプッシュは何かと大げさになりがちという話をされてましたね」「プッシュの仕組みはいろいろあるけど実装がかなり違うので、こういう共通化層がないとしんどいですね😭」
⚓RubyMine更新情報(Ruby Weeklyより)
つっつきボイス:「RubyMineはやっぱりいいな(しみじみ)「よさげな機能あるかな?」
「メソッドへの切り出しの改良が多いみたい」「切り出しで同じことやってる部分も見つけて置き換える↓」
「show usageでそのメソッドが使われている場所を表示する機能は前からあったっぽいけど、Railsのコードを追いかけたりするのに便利かな」「findするのと同じ?」「結果は同じですが、RubyMineのキャッシュに乗る分速いでしょうね😋」
「置き換え時にExcludeで除外を指定できる機能も前からあったかな」「知らなかった〜」「置き換え、やるとついイケないところまで置き換えちゃうんで基本使ってない😅」「ファイル名をリネームするときに事故りやすい傾向あるかも」
「サブストリングを変数や定数に切り出す機能↓もなかなか」「使うことあるかな?とも思うけど、すごく込み入っているときなんかに役立つかも」「JavaだとEclipseにこの手の機能があった気がするけど、それをRubyとかRailsでできるのがスゴイ」
「手取り足取りというか痒いところに手が届くような改善😃」「だいたいIntelliJ IDEA本体での改善でしょうから、他のJetBrains IDEでも使えそう😋」
⚓Martin Fowler『Refactoring 2nd Edition』が予約開始
3月のウォッチで同書の情報をお伝えしていましたが、やっとAmazonで予約開始ということのようです。
つっつきボイス:「おぉ、Martin FowlerのRefactoring」「基本的にJavaが対象だったかな」「あれ、2nd EditionはJavaScriptにも対応したと聞いてたけど?」「あ、ほんとだ💦」「今ならJavaScript入れる戦略でしょうね」「まだ英語版しか出ないのか」「それも11月末発売で」
「Ruby版のRefactoringも2nd Edition出るといいですね🍭」「Martin先生がRuby版出すかな〜🤔: Javaというかプログラミング設計の大物ですね」
後で調べると、Refactoring Ruby EditionではMartin先生はメインの著者ではないそうです。
⚓BrowserifyからWebpackへ
手元のこのレガシーアプリ、小規模のRailsなんだけど、今日はapp/assets以下をだいたい剥がしてwebpackに寄せれた。自分でやってよくわかったけど、HTML、CSS、アセットを返す昔ながらのWebアプリケーションフレームワークとまるで思想が違うので、共存させようとした時点でメタゲームで負けてた。 https://t.co/HFqyrIh0j4
— yasaichi (@_yasaichi) September 17, 2018
つっつきボイス:「Browserify、あったなーそんなの😆」「app/assets以下を整理してWebpackに移行するとか大変そう: 結局Sprockets系のアセットヘルパーを全部Webpack用に直さないといけないので😔」「私もオレオレRailsアプリでこれやりたいと思ってるんですが手こずりそうで😅」「素直なCSSで書かれているだけならすぐ寄せられるんですけど、変数展開とか使ってたりすると一気に難しくなってつらい」
参考: Browserify: それはrequire()を使うための魔法の杖 - Qiita
⚓その他Rails
銀座Rails#1懇親会、空き枠が残り3つとなっております。
スピーカーの方と美味しいビールを飲みたい方は是非どうぞ。
なお終了時刻が遅くなっておりますが、途中退出も可能です。https://t.co/8weDjpYqPS— 銀座Rails (@GinzaRails) September 20, 2018
つっつきボイス:「ちょうど私たちのつっつき会と同じ時間帯にやってるようです」
⚓Ruby trunkより
⚓Rubyのキーワード引数の今後
先週ちらっと触れたキーワード引数スライドですが、今日社内勉強会でも発表して引数周りを少し追いました。正直、以下に共感します。
まあ Ruby の Symbol と String は慣れたらそういうもんだなーと1度理解すればそこまで問題にはならないんだけど、やっぱり Hash のキーが Symbol なのか String なのか混ざっている時にわけわからなくなるのがなー
— バンビちゃん@実際パリピになれないオタク (@pink_bangbi) September 17, 2018
つっつきボイス:「今日の勉強会の発表はよかったっす💪」「ありがとうございます🙇: TechRacho記事にまとめます」「キーワード引数はいろいろヤバい」「勉強会でも話したけど、どうして動くのかわからないのに動いているのが一番つらい😆」「メソッド呼び出しでnil
足したら動いた話でしたっけ?」「nil
足して動くようなのは全然大したことなくて、メソッド定義を見ればだいたい納得がいくんですが、define_method
とかsend
、public_send
あたりが絡むとヤバいんじゃないかと思う」「メソッド定義を見てもさっぱりわからないヤツ😭」「メタプロですね」「受け取った引数をそのまま渡している箇所が想定から外れているのにたまたま動いていて、breaking changesが入って制約が厳しくなるとあちこちで火を噴く、なんてことがありそうで」「エラーで落ちるならまだいいんだけど、違う解釈で通ってしまったりするとコワイ😰」「さすがにそういう変更はかけないかな: 警告出して落とすことはすると思う」「大江戸Ruby会議 07でもwarning出す方向で考えると言ってました」
参考: instance method Module#define_method
(Ruby 2.5.0)
参考: instance method Object#__send__ (Ruby 2.5.0)
参考: instance method Object#public_send
(Ruby 2.5.0)
「ツイートの『Hash のキーが Symbol なのか String なのか混ざっている時にわけわからなくなる』、ほんにこれ」「そうそうそう!😤」「そんなときのためのHashWithIndifferentAccess
↓という神クラスですよ: これがデフォルトの動作でいいんじゃないかと思うこともあるけど、ハッシュのキーをオブジェクトにしたい場合もありますからね😎」
参考: ActiveSupport::HashWithIndifferentAccess
「普通のハッシュとは別に、シンボルだけをキーに取るシンボルハッシュみたいなものがあるといいんじゃないかと思うことある」「それ欲しいヤツ!」「でなければ、今のハッシュをシンボル専用にして、任意のオブジェクトをキーにしたいときはそれ専用のObjHashみたいなものを別に用意するとか」「ハッシュのキーはほとんどの場合シンボルにしますからね」「breaking changesになるからやらないでしょうけど🤔」
「そういえば大江戸Ruby会議07で、『シンボルでハイフンが使えたらうれしい』という意見を見かけました」「あ、シンボルリテラルでハイフンを使いたいってこと?」「ですね: ""
で囲まずにやりたいと」「パーサーに怒られそう😆」「でも今のRubyはこういう書き方↓ができるから随分楽になりましたね😋」「あー、式展開で任意の文字列をシンボルにするのか😳」「ですです😎」「これが使えるから今のRubyのシンボルリテラル周りはだいたい満足✨」
[1] pry(main)> :'hogehoge'
=> :hogehoge
[2] pry(main)> piyo = '1-29eikdmfc/~!@#$%'
=> "1-29eikdmfc/~!@\#$%"
[3] pry(main)> :"hoge#{piyo}"
=> :"hoge1-29eikdmfc/~!@\#$%"
⚓Ruby
⚓Apache OpenWhiskでRubyがネイティブサポート
Link: Ruby goes Serverless! - Apache OpenWhisk adds native support for Ruby https://t.co/8GUpKMUqQ3
— Yukihiro Matz (@yukihiro_matz) September 18, 2018
- サイト: Apache OpenWhisk is a serverless, open source cloud platform
- リポジトリ: apache/incubator-openwhisk-runtime-ruby
つっつきボイス:「OpenWhisk?」「FaaS(Function as a Service)ということで、AWSでいうLambdaに相当しそう」「at any scaleで↓こういうものを使って構築できるということみたい」
「Apacheのプロジェクトですが、Apache Webサーバーとは関係なさそう?」「少々紛らわしいんですがWebサーバーとは別で、いわゆる「Apache Projects」ですね: ApacheではWebサーバー以外にもものすごくたくさんのプロジェクトが動いてます↓」「え、こんなにいっぱいあるんだ!😳」「しかも質の高いものが多いことで知られてます🧐: あのHadoopもHBaseもApache Projectsだし」「へー!」「kafkaもRubyKaigiで登場してましたね」「karafkaですね」「CloudStackもApache Projectsなのかー」
「ちなみにRubyバインディングのincubator-openwhisk-runtime-rubyは今の所★はゼロですが」「まあKubernetesにデプロイできるということはGCPなんかにもすっと置けそうですね😊」
「ちょっと話逸れますが、大江戸Ruby会議07で、AWSのDockerコンテナよりGCPのDockerコンテナの方が速いという話題が出てました↓」「AWSのコンテナは結局のところEC2のVMの上で動くんですが、Googleなら専用ハードウェア上で動かすとかやってるかもしれない: この辺はあくまで推測ですが」「おー」「GoogleならLinuxカーネルにも手を加えていそうだし: AWSはあくまで普通のLinuxカーネルなので(Amazon Linuxというのもあるけど)」「ふむふむ」「だとするとGCPのコンテナはその環境に依存して他のコンテナサービスだとうまく動かないとかたまにあったりするのかな?」
ECRはすごい遅い。 GCPの同じやつはめっちゃ早いのでこれを使うのが正解wwwww #oedo07
— おおた (@ota42y) September 15, 2018
ECRの遅さにキレてる人多数w #oedo07
— joker1007 (アルフォートおじさん) (@joker1007) September 15, 2018
⚓RSpecの原理を単独で学べるGist(Ruby Weeklyより)
つっつきボイス:「お、このコード単体で実行できるのね」「まさに先週のウォッチに出てきたbundler/inline
を使ってる」「ですです: このままirbに貼り付けて動きます😃」「シンプルでわかりやすくていいんじゃない😋」
「こういうのでRSpecにもっと親しみが持てるようになるかしら?」「いや〜それは中々😆: RSpecで最初につまずくのはこういうexpect
↓で引数をかっこ()
で渡すのかブロック{}
で渡すのかというところ」「そうそう😆」
# 同Gistより
expect(foo).to have_value(1)
「そしてかっこで渡す場合とブロックで渡す場合でかなり挙動が変わるし😭」「はぁー😳」「そしてブロックで渡したときだけraiseで取れるし」「そうそう」「じゃ全部ブロックにすればいいかというと、マッチャーによってはできないものがあるという」「苦労の連続😢」
⚓benchmark-trend: Rubyのベンチマーク(Ruby Weeklyより)
- リポジトリ: piotrmurach/benchmark-trend
# 同リポジトリより
print trends
# =>
# {:exponential=>
# {:trend=>"1.38 * 0.00^x",
# :slope=>1.382889711685203,
# :intercept=>3.822775903539121e-06,
# :residual=>0.9052392775178072},
# :power=>
# {:trend=>"0.00 * x^2.11",
# :slope=>2.4911044372815657e-06,
# :intercept=>2.1138475434240918,
# :residual=>0.5623418036957115},
# :linear=>
# {:trend=>"0.00 + -0.01*x",
# :slope=>0.0028434594496586007,
# :intercept=>-0.01370769842204958,
# :residual=>0.7290365425188893},
# :logarithmic=>
# {:trend=>"0.02 + -0.02*ln(x)",
# :slope=>0.01738674709454521,
# :intercept=>-0.015489004560847924,
# :residual=>0.3982368125757882}}
つっつきボイス:「あー、こんなふうに↓rangeで値を変えてベンチマークを取れるのか」「数値そのものの意味がよくわからないんで何とも言えないけど、値を変えていったときに指数(exponential)、power(乗数)、線形(linear)、対数(logarithmic)でパフォーマンスが落ちていく様子が取れるっぽい」「何かのモデルに沿ってるのかな?」「これを信用するかどうかだけど、ちゃんと使えば有用なのかもしれない」「実際にベンチマーク取ってるからプロットしちゃえばいいじゃんという気はするけど😆、このgemはプロットの近似の式まで出してくれている」「たぶん自分用のツールなんでしょうね」「そんな気はするけど筋はよさそう😊」
# 同リポジトリより
Benchmark::Trend.range(8, 8 << 10, ratio: 2)
# => [8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192]
⚓Rubyのredo
キーワード(Ruby Weeklyより)
# 同記事より
for i in 1..3 do
puts "Iteration #{i}"
redo if i == 1
puts 'After redo'
end
# produces:
#
# Iteration 1
# Iteration 1
# Iteration 1
# Iteration 1
# ... infinite loop
つっつきボイス:「redo
ってキーワードあったなそういえば: ちなみにRubyにはcontinue
はない」「redo
ってnext
と違うやつで、next
はイテレーションするけどredo
はイテレーションせずに文字どおりそのループをもう一回やり直す」「まあredo
ってあんまり使ったことないけどw、Rubyの基本構文として随分前からあるはず」
⚓Brighton Ruby Conference 2018のVimeo動画
- 動画リスト: Vimeo -- Andy Croll
Boring Ruby Code - Adam Niedzielski from Andy Croll on Vimeo.
2018年7月に開催されたBrighton Ruby Conference 2018のの動画を、TechRachoの翻訳記事でお世話になっているAndy Croll氏↓がVimeoにアップしているのを見つけました。
つっつきボイス:「海外のRuby Conferenceか」「イギリスのBrightonですね」「スライドが欲しいスライドが」「上のBoring Ruby Codeとかタイトルだけ見るとちょっと面白そう」「やな感じのsend
↓」「式展開してるし😰」
⚓Persistent-💎: Rubyのイミュータブルデータ構造
# 同リポジトリより
my_array = a💎[1, 2, 3]
思い切り絵文字使ってます。
つっつきボイス:「珍しくGitLabでやってるし」「何だこれは😳」「Rubyでこんなことする人ときどき見かけるし」「💎
を付けるとfreezeしたものを返すだけみたい: 完璧にお遊びですね🏖」
たぶん「007 ダイヤモンドは永遠に」にかけてるんでしょうね。
⚓その他Ruby
mrubyにString#trを実装したが、参考にしたコードがBSDライセンスだったので、MITのmrubyに含めるために交渉が必要になった。
— Yukihiro Matz (@yukihiro_matz) September 20, 2018
つっつきボイス:「tr
って何だっけ」「正規表現を使わずに文字列を置き換えるやつだったと思います」「そうそう、正規表現だとたいてい遅い」
参考: instance method String#tr
(Ruby 2.5.0)
「そういえば何でtr
って名前なんだろ?」「(ググって)あー、Linuxのtr
コマンドが元なのか」「man tr
するとtranslate characterと出た」「頭の2文字でtr
と略したんだろな」
参考: tr
- コマンド (プログラム) の説明 - Linux コマンド集 一覧表
⚓クラウド/コンテナ/インフラ/Linux/Serverless
⚓さくらのDockerホスティングサービス「Arukas」
- サイト: Arukas|Dockerホスティング
参考: Arukasハンズオン資料 - 基本操作編 - Qiita
参考: Arukasハンズオン資料 - 事前準備編 - Qiita
参考: Docker の基本学習 ~ コンテナ間のリンク - Qiita
つっつきボイス:「今日の社内チームミーティングで発表されてたので」「どのぐらい本気出すかが気になるところ😎」「Herokuのライバル的な」「価格でもうひと頑張りしてくれたらな〜」
⚓SQL
⚓PostgreSQLのCTEは取扱い注意(Postgres Weeklyより)
つっつきボイス:「CTE = Common Table Expressions」「うは、ぽすぐれだとこんな構文なのか↓」「そしてCTEだと数百倍遅いことがあると」「毎回評価されて遅くなるとかそんな感じ?」
-- 同記事より
haki=# with cte as (select * from foo) select * from cte where id = 500000;
id | padding
— — — — — — — — — — — — — — — — — — — — —
500000 | b292eb19f3145fb087648d5956dfa44e
Time: 227.675 ms
「ぽすぐれのドキュメントで見ると、WITH
のtop_regions
で取ったものをWHERE region IN (SELECT region FROM top_regions)
のところで参照できるということか↓」「つまり入れ子のSELECT文を事前に呼んでおいてメインのところでコンパクトにすっきり呼び出せるという」「ほぅほぅ😊!」「Withって何だかVBみたい😆」「RECURSIVEで自己参照もできるし」「普通はできないヤツなのに、ぽすぐれやるな〜💪」
-- postgresql.jpより
WITH regional_sales AS (
SELECT region, SUM(amount) AS total_sales
FROM orders
GROUP BY region
), top_regions AS (
SELECT region
FROM regional_sales
WHERE total_sales > (SELECT SUM(total_sales)/10 FROM regional_sales)
)
SELECT region,
product,
SUM(quantity) AS product_units,
SUM(amount) AS product_sales
FROM orders
WHERE region IN (SELECT region FROM top_regions)
GROUP BY region, product;
参考: WITH問い合わせ(共通テーブル式)
参考: With
...End With
ステートメント (Visual Basic)
⚓JavaScript
⚓目新しいJSライブラリを評価するときの12個のポイント(JavaScript Weeklyより)
つっつきボイス:「普通にチェックする部分かなと思いつつ」「絵文字がカワイイ🐻」「Momentumはいわゆる『勢い』ですね」
⚓「アレ」する方法をPythonとJSで比べてみた(JavaScript Weeklyより)
これのRuby版があってもいいのかも?
つっつきボイス:「PythonのアレはJavaScriptでどう書くんだっけ?のチートシート」「そういえばPHPのあの関数はRubyではどう書くかみたいなのはよく使ってたし」
⚓CSS/HTML/フロントエンド/テスト
⚓jxck.ioの「次世代 Web カンファレンス 2019」
つっつきボイス:「あのjxck.ioの中の人が、ちょっとコワモテのWebカンファレンスを来年開催するそうです」「会場は法政大学か」「発言は個人としてのみを前提」「お金は扱わないと」「事前の仕込みはなしで、純粋に討論だけでやるのね」「こういう話がしたいんだろうな〜ワカル😊: W3CとかWHATWGはあまりこういう感じでディスカッションとかしなさそうだし」「パネラーも錚々たるメンバー: お、知ってる人もいる」「研究系のカンファレンスに近いかな」「これはかなり面白そう: 話についていくのは中々大変だと思うけど😎」
⚓ドワンゴの「Webフロントエンド パフォーマンス改善ハンドブック」
つっつきボイス:「そうそう、こういうパフォーマンス改善の常識ってどんどん大きく変わっていくんですよね〜Chromeとかの最適化なんかで変わってきたりとか」「個別の要素には普遍的なものも多いんですけど、具体的な手順なんかが変わったりする: 昔はこれこれの項目をチェックしなければいけなかったけど今はJSのJITが効いて高速化したのでスルーされたりとか」「移り変わり激しい🏎」「このハンドブックは新しいのでそのあたり追従してる感じですね」
⚓その他CSS/HTML/フロントエンド/テスト
今日のわかばちゃんです
/ #マンガでわかるDocker ② #技術書典 #技術書典5https://t.co/MLn5avUxtI pic.twitter.com/yWi27dYlRP
— 湊川あい📚IT漫画家 わかばちゃんと学ぶ シリーズ発売中 (@llminatoll) September 19, 2018
つっつきボイス:「社内Slackで投下していただいたヤツです」「いつの間にかシリーズ化してるし」「わかばちゃんつぇ〜🌱」
⚓言語よろずの間
⚓Phusion PassengerがC++からGoへの移行を表明
- 元記事: Migrating Passenger from C++ to Go?
- Issue: Migrating Passenger from C++ to Go · Issue #2118 · phusion/passenger
つっつきボイス:「へぇー、PassengerがGolangに行くのか」「Go言語はミドルウェアに向いているし、最低限のコンテナとして動かすにはとても向いていると思うので、C++で頑張るよりはいいんじゃないかな😋」「私もそう思います😊」
⚓その他
⚓Twitterのタイムライン
おお、わしが欲しかったのはこれや〜!というわけで早速設定してみた。Twitterはやっぱりこうでないと。
Twitter、シンプルな時系列表示が可能に(Impress Watch) - Yahoo!ニュース https://t.co/3e87edQim6— Junichi Ito (伊藤淳一) (@jnchito) September 18, 2018
つっつきボイス:「お、いつの間に」「私も早速オフにしました📉」
⚓番外
⚓「世界を変えた書物」展
『[世界を変えた書物]展』開館いたしました。
開館時間10:00〜17:00(最終入館16:30)、入場無料。会期は9月24日(月・休)まで、会期中無休です。是非ご来館くださいませ。 pic.twitter.com/BMWHUduOPJ— 上野の森美術館 (@UenoMoriMuseum) September 15, 2018
展示は残念ながら昨日24日で終了ですが、私は家族で見に行っちゃいました😋。
つっつきボイス:「展示が無料だったというのが主な理由で😆」「活版印刷前のはあった?」「さすがに印刷機登場以後でした: 時代が新しくなるに連れて印刷がどんどん精密になっていてスゴイなとも思ったし、昔は本を出版するのってめちゃめちゃ金がかかったんだろうなというのが想像つきました」「装丁とか挿絵とか図とかね😊」「作者自ら銅版画に鉄筆で図を描いたりとか苦労が偲ばれました」
⚓数学ニュース2つ
ここ数日話題になってます。ABC予想について望月新一教授が2012年に発表した証明に修復不能なギャップが見つかったというニュース(望月教授は現在反論中)と、89歳の英国数学者Michale Atiyah教授がリーマン予想を証明したと主張しているという記事です。
しかし早速続報が↓。
サイエンス誌が、アティア先生のリーマン予想の"証明"を取り巻く疑念を紹介してる。まともな証明になってないと多くの人が思ってるのが現状。
Skepticism surrounds renowned mathematician’s attempted proof of 160-year-old hypothesis https://t.co/47ltU81uXy— Masahiro Hotta (@hottaqu) September 25, 2018
今回のアティヤ先生の研究がボロクソな扱いを受けてる件からも、数学や物理学の研究は、著者の高名さとか権威とか関係なく、飽くまで内容次第ということが若い人にも分かって頂けるかと思います。これが正常な学術界というものです。フィールズ賞やノーベル賞をとっていても、それは変わらないのです。
— Masahiro Hotta (@hottaqu) September 25, 2018
今回は以上です。
バックナンバー(2018年度後半)
週刊Railsウォッチ(20180918)ビューテンプレート探索が高速化、mini_scheduler gem、レガシコントローラのリファクタリングほか
- 20180910 公開つっつき会#2、RSpecは何を参考にするか、イベントソーシング、marginalia gem、負荷テストツールvegetaほか
- 20180903 次世代アップローダーgem「Shrine」、RSpecをどこまでDRYに書くか、Rubyのmainオブジェクトの秘密、GitLabのCookie利用許諾機能はエライほか
- 20180827 Ruby Prize 2018募集開始、Interactor gemとReader Object、書籍『Real World HTTP』、Basecampのヒルチャート機能ほか
- 20180820 Railsで構築されたサイト40選、Deviseはつらいよ、ARのスコープとクラスメソッドの使い分けほか
- 20180813 Rails 5.2.1リリース、sanitize_sql_arrayは5.2からpublicだった、Dev.toがRailsアプリのソースを公開ほか
- 20180806 Rails 5.2.1.rc1リリース、Railsガイド日本語版が5.1に対応、Regexp#match?ほか
- 20180723 Railsdm Day 3 Extremeを後追い、PSDにはZeplin.io、好みの分かれるJSX、負荷テストツール比較ほか
- 20180709 Rails Developers Meetup Day 3 Extreme今週末開催、RailsのSTI/キャッシュ/添付ファイル/Redis/PDF出力、ECMAScript 2018、プロフェッショナルIPv6ほか
- 20180702 Ruby 2.2メンテ正式終了、Ransackがつらくなるとき、書籍『Domain-Driven Rails』、GitHubの高可用MySQLほか
- 20180622 Railsの需要未だ巨大、Unicode 11.0リリース、WebDriverがW3Cで勧告、Flutter.io、2封筒問題ほか
- 20180615 TTY gemとHTTPClient gemは優秀、Rubyの謎フリップフロップ、ちょいゆるRubyスタイルガイドほか
- 20180608 特集「RubyKaigi 2018後の祭り」、
Enumerable#index_with
は優秀、コントローラから@
を消し去るほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやRSSなど)です。