Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

週刊Railsウォッチ(20200804後編)「RubyKaigi Takeout 2020」9月オンライン開催、メールバリデータtruemail、Gitのmasterが変更可能にほか

こんにちは、hachi8833です。「Kaigi on Rails」のプロポーザルがいっぱい集まったそうです🎉。

さらにこんなイベントもあったことに後から気づきました。

  • 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄

Ruby

臨時ニュース: 「RubyKaigi Takeout 2020」が9月4〜5日にオンライン開催

ついさっき知りました。詳細はこれからのようですが、わずか1か月先なんですね。

最近のRuboCop Railsアップデート

少し前に本体にpendingモードが導入されたことをやっと知りました↓。

参考: RuboCop 0.79.0 リリース解説 - koicの日記


つっつきボイス:「RuboCop 0.80ぐらいから新しいcopをいきなり有効にしなくなっていたそうです」「動いているプロジェクトにとってはその方がありがたいですよね」

「それにしてもRuboCopのルール多いな〜」「これもルールにするの?みたいなのまで入ることもありますし」「素の設定で開発している人っているんだろうかと思ったり」「自分も新し目の設定はyamlで黙らせちゃうこと多いです😆」

Rubyのメソッドオーバーロード


つっつきボイス:「オーバーロードで遊んでみたという記事ですが、やってみたらやっぱりだいぶ遅かったみたいです」

「そしたらWeaverさんがもっと速くしてみたそうです↓」「できるのはわかったけど、使うかな〜?」「C++かと思った」「Twitterのスレには他にもいくつかコードやgemがあったんですけど、だいたい『業務では使うな』って書いてありました🤣」

# Warming up --------------------------------------
#   method overloading   126.264k i/100ms
#               method   255.798k i/100ms
# Calculating -------------------------------------
#   method overloading      1.711M (± 8.2%) i/s -      8.586M in   5.057014s
#               method      5.697M (± 3.3%) i/s -     28.649M in   5.035081s

# Comparison:
#               method:  5696723.0 i/s
#   method overloading:  1711428.7 i/s - 3.33x  slower

「C++のようにメソッドの引数も含めてシグネチャになる言語だとオーバーロードでやるんでしょうけど、Rubyならオーバーロードしなくてもやれますし」「やってみたかったのでやった系の記事なんでしょうね」

参考: メソッドのシグネチャ(signature)とメソッドの構文(syntax)の違い - いっしきまさひこBLOG

truemail: フレームワークを問わないメールバリデータ(Ruby Weeklyより)

rubygarage/truemail - GitHub


同リポジトリより

Truemail.configuration

=> #<Truemail::Configuration:0x000055590cb17b40
 @connection_timeout=1,
 @email_pattern=/regex_pattern/,
 @smtp_error_body_pattern=/regex_pattern/,
 @response_timeout=1,
 @connection_attempts=3,
 @validation_type_by_domain={},
 @whitelisted_domains=[],
 @whitelist_validation=true,
 @blacklisted_domains=[],
 @verifier_domain="somedomain.com",
 @verifier_email="verifier@example.com",
 @not_rfc_mx_lookup_flow=true,
 @smtp_safe_check=true,
 @logger=#<Truemail::Logger:0x0000557f837450b0
   @event=:all, @file="/home/app/log/truemail.log", @stdout=true>>

つっつきボイス:「メールのバリデーターだそうです」「なるほど、書式チェックだけじゃなくて許可/不許可リストとかとの照合もしてくれると」「SPFやDKIMあたりも見てくれるのかな?」

後で調べると、truemailにはSPF/DKIMは入っていませんでした。

参考: 受信時の送信ドメイン認証(SPF/DKIM) | メール機能 | 共用サーバー標準 | 共用サーバー | サービス | レンタルサーバーのWADAX

「こうやって許可/不許可リストのドメインも定義できるのね↓」「いい感じにカスタマイズしてメールバリデーターにできそう」「うれしい人はきっとうれしい😂」「MXバリデーションができるのもよさげ」「メールアドレスをタイポしたときにもある程度検出できるかも」「メアドを厳密にチェックしたいときなんかにいいでしょうね👍」

# 同リポジトリより
require 'truemail'

Truemail.configure do |config|
  config.verifier_email = 'verifier@example.com'
  config.whitelisted_domains = ['white-domain.com', 'somedomain.com']
  config.blacklisted_domains = ['black-domain.com', 'somedomain.com']
  config.validation_type_for = { 'somedomain.com' => :mx }
end

「よくわからん正規表現書かなくてよくなりそう」「メアドチェックの正規表現を自分で書くのはもう無理😇」「地獄」「正規表現が長くなると重くなりますし」

その他Ruby

つっつきボイス:「RubyGemsのブログは、rubygems.orgのAPIキーがHoneycom.ioのイベントログに出てしまっていたのを直したという記事でした: RSSリーダーで個人ダッシュボードのRSSをフィードしている人だけ影響していた可能性があるそうです」「何と!」「2つ目は年末恒例のFukuoka Ruby Awardのエントリ募集のお知らせです」


Aaron Pattersonさんの動画セッション(Ruby Weeklyより)

「@tenderloveさんの動画はチラ見しただけですが、インスタンス変数使いすぎると遅くなるぞ、どれだけ遅くなるか調べたという感じの内容でした」「@tenderloveさん個人のYouTubeチャンネルかと思ったらBoulder Rubyのチャンネルなのね↓」

参考: Boulder Ruby Group (Boulder, CO) | Meetup


「知名度の高いMatzがこういう話↓をフォローしてくれるところがありがたいですよね」「プログラミングを必修授業にしたらプログラミングがキライになる人がきっと大量生産されるとマジ思いますし」

必修、つまり義務化すると、適性のない子でもいやいや勉強をしなくてはならない。これを強制すると、結果的にプログラミング嫌いの子供を大量に生むことになって、逆効果になるんじゃないかと思ったからです。
同記事より

「自分も体育でやらされてサッカー嫌いになりましたし」「先生が嫌いになるとその科目まで嫌いになるというパターン」「で社会に出てからその科目を勉強してみたら思った以上に面白かったり」「そうやって遠回りしがちですよね…」「私も技術家庭の時間がいやでいやでしょうがありませんでしたし」「え?技術とか大好きそうですけど?」「先生が嫌いだったので😅」「授業と縁がなくなってくると面白くなるという」「数学大嫌いだったのに今は本とか買っちゃいますし」「数学って授業じゃないとあんなに面白いのに😆」

思い返すと自分は嫌な先生に出会ったことがなかったのが幸運だったかもしれません。単に忘れっぽいだけかもしれませんが。

DB

アプリケーションDBAが教えるSQLの技(StatusCode Weeklyより)


つっつきボイス:「これは主にPostgreSQLの話みたい」「WAL(Write Ahead Log)とかはぽすぐれの仕様にありますね」

参考: 29.2. ログ先行書き込み(WAL)

「へ〜、UNLOGGEDテーブルってのがあるのね」

-- 同記事より
db=# CREATE UNLOGGED TABLE duplicate_users AS
db-#     SELECT
db-#         lower(email) AS normalized_email,
db-#         min(id) AS convert_to_user,
db-#         array_remove(ARRAY_AGG(id), min(id)) as convert_from_users
db-#     FROM
db-#         users
db-#     GROUP BY
db-#         normalized_email
db-#     HAVING
db-#         count(*) > 1;
CREATE TABLE

db=# SELECT * FROM duplicate_users;
 normalized_email  | convert_to_user | convert_from_users
-------------------+-----------------+--------------------
 me@hakibenita.com |               2 | {3}

参考: PostgreSQL 10の Unlogged Table と Declarative Partitioning - Qiita

「WITHとRETURNINGを使う話」「正規化されてないデータをこうやってCTE(Common Table Expressions)とかで直したり無理やり取り出したりできる感じですね」

-- 同記事より
WITH duplicate_users AS (
    SELECT
        min(id) AS convert_to_user,
        array_remove(ARRAY_AGG(id), min(id)) as convert_from_users
    FROM
        users
    GROUP BY
        lower(email)
    HAVING
        count(*) > 1
),

update_orders_of_duplicate_users AS (
    UPDATE
        orders o
    SET
        user_id = du.convert_to_user
    FROM
        duplicate_users du
    WHERE
        o.user_id = ANY(du.convert_from_users)
    RETURNING o.id
),

delete_duplicate_user AS (
    DELETE FROM
        users
    WHERE
        id IN (
            SELECT unnest(convert_from_users)
            FROM duplicate_users
        )
        RETURNING id
)

SELECT
    (SELECT count(*) FROM update_orders_of_duplicate_users) AS orders_updated,
    (SELECT count(*) FROM delete_duplicate_user) AS users_deleted
;

参考: 7.8. WITH問い合わせ(共通テーブル式)

「low selectivityってあるのはいわゆるカーディナリティのことでしょうか?」「ここではカーディナリティのようですね」

-- 同記事より
db=# INSERT INTO users (username, activated)
db-# SELECT
db-#     md5(random()::text) AS username,
db-#     random() < 0.9 AS activated
db-# FROM
db-#     generate_series(1, 1000000);
INSERT 0 1000000

db=# SELECT activated, count(*) FROM users GROUP BY activated;
 activated | count
-----------+--------
 f         | 102567
 t         | 897433

db=# VACUUM ANALYZE users;
VACUUM

参考: MySQL(InnoDB)でカーディナリティの低いカラムにINDEXを張る - Qiita

「partial indexはぽすぐれ独自の機能みたい」「へ〜こんなことができるんだ↓: これならカーディナリティの高い部分にだけインデックスを効かせたりできますね」「ここまで細かくDBを世話するかどうかですけど、でかいデータだと効果大きそう」

-- 同記事より
db=# CREATE INDEX users_unactivated_partial_ix ON users(id)
db-# WHERE not activated;
CREATE INDEX

「CLUSTERコマンドとか知らないものもあるな」

参考: CLUSTER

「BRIN(Block Range INdex)はインデックスの種類だったかな: 普段使うというより、困ったときに調べて使う機能」「ぽすぐれ、懐が深いですね」

参考: 67 BRINインデックス

「最後の『時間のかかるプロセスの開始はx時ジャストを避けよ』はぽすぐれに限らず言えるヤツですね: x時ちょうどにバッチを開始すると他のバッチも同じ瞬間に起動して負荷が上がる可能性が高いから気をつけないと」「あ〜それですか」「最近のRailsに入ってきたjitterもそういうのを避けるのに使えますし(ウォッチ20191216)」「RailsのActive Jobみたいにジョブをキックする機能にはよくこういうオプションがあります」

「気持ち的にはx時ジャストに動かしたいですけど」「まあジャストにする積極的な意味がないなら記事にもあるようにsystemdのRandomizedDelaySecとかでかわすのがいいでしょうね」「ぽすぐれの機能かと思ったらsystemdでしたか」「cronもanacronあたりを使えばやれたと思います」

参考: systemd - Wikipedia
参考: anacron - Wikipedia

「Railsだとjitterって言うのか〜」「まあ実際は数分もずれたりしませんし、誤差程度にしかずれないから問題にはならないでしょう」「開始タイミングをちょっとずらすことが身を助けることもあるんですね」「ごく短い瞬間にタスクが集中するとそういう問題が起きやすいので」

「全体にDBAのノウハウ記事としてよさそう👍」


目次より:

  • 更新が必要なものだけをUPDATEすること
  • バルク読み込み中は制約やインデックスをオフにすること
  • 中間データはUNLOGGEDテーブルに置くこと
  • プロセス完了の実装にWITHとRETURNINGを使う
  • カーディナリティの低いカラムへのインデックス作成は避けること
  • 部分インデックスを活用しよう
  • 常にソート済みのデータを読み込むこと
  • カラムのインデックスの相関をBRINインデックスで高める
  • インデックスを「見えなくする」技
  • 時間のかかるプロセスの開始は「x時ジャスト」を避けること
  • まとめ

その他DB

クラウド/コンテナ/インフラ/Serverless

AWS Fraud Detectorがリリース(StatusCode Weeklyより)


つっつきボイス:「元記事は英語でしたがもう日本語版出てました」「fraudは不正」「オンライン活動を簡単に特定できるマネージドサービスですか」

「ある程度以上の規模のサイトになるとこういう不正検知を自分たちで作りますけど、不正検知のアルゴリズムを自分で書かなくてもその部分をAWSに外出しできるようになったという感じ」「モデルのトレーニングの話とかも出ているので、おそらく教師データを自分たちで突っ込むといい感じに動いてくれそう」

「こういうインテリジェントな機能がAWSにあるなら使うかも」「外部の有償サービスを導入するよりはやりやすそうですね」

JavaScript

フロントエンドクライアント(GraphQL)でJWTを扱う究極ガイド


つっつきボイス:「徳丸先生がイチオシしてた記事」「そのアーキテクチャを選んだ理由がちゃんと書かれているのがよいと」「JWTトークン、ゆくゆくは必要になってくるのかな」「ざっと覗いてみた感じだととても親切に書かれてるっぽい😋」

「アーキテクチャ設計では、まず前提条件があって、それに基づいてアーキテクチャを選ぶというのは当然かつ重要ですね」「何となくこれにしてみた、ではないと」「世の中でこれがベストプラクティスとされているからこれにした、が理由のひとつにあるぐらいならまあいいかなとは思いますが、この設計は他と比べてここが有利とか、仕様上の条件や性能指標はこの設計で十分満たせる、というところまで持っていくのが重要」

「JWTのようなAPI認証系は後になっていじりたくない部分の筆頭ですよね😆」


見出しより:

  • JWTとは
    • セキュリティ上の懸念点
    • JWTの構成
    • セッショントークンではなくJWTを使う理由
  • ログイン
    • トークンを永続化するかどうか
    • クライアント側でのトークンの利用
  • JWTでGraphQLクライアントをセットアップする
    • トークン期限を扱う
    • エラーハンドリング
  • ログアウト
    • トークンの無効化
    • トークンの「不許可リスト」
  • サイレントリフレッシュ
    • トークンをリフレッシュするしくみ
    • リフレッシュしたトークンの保存場所をどうするか
    • トークンのリフレッシュを伴うログインフロー
    • トークンの期限が切れたときのリフレッシュ
  • セッションの永続化
    • セキュリティ上の懸念点
    • エラーハンドリング
  • 強制ログアウト
  • SSR(Server Side Rendering)

言語/ツール/OS/CPU

パタヘネとヘネパタ

パタヘネって今も更新され続けているんですね。この間セールで買ったKindleの第5版(上下巻)ではMIPSでしたが、次の版はRISC-Vとやらを使うようです。

参考: RISC-V - Wikipedia


つっつきボイス:「この間Amazonでパタヘネ第5版の上下巻Kindle版がセールだったので買っちゃったんですが、少なくとも自分にとっては感激する本でした」「これって何の本ですか?」「文字どおり『コンピュータの構成と設計』😆」「MIPSっていうプロセッサをお題に機械語やアセンブラの動作を中心にがっつり解説してます」

参考: MIPSアーキテクチャ - Wikipedia

「まだ流し読んだ程度ですけど、何しろ自分が大昔に初めて覚えた言語が8080アセンブラだったので、当時と比べてすごい進歩だなと😂」

参考: Intel 8080 - Wikipedia

「その記事によると翻訳の質がイマイチみたいですけど?」「いえ、用語を日本語の熟語で表す傾向がややあるかなとは思いましたけど、誤植も少なかったし自分が読んだ限りでは全般にとてもしっかり訳してあっていいと思います👍」「じゃ自分もKindle版ポチっちゃおうかな…ありゃ上巻だけ買っちゃった?」「😆」「今ならキャンセルして買い直せると思いますよ」

「このパタヘネは米国西海岸などの大学でのコンピュータサイエンス(CS)の学部向け教科書として書かれているんですよ: もう明らかに授業で使うための本」「あ〜なるほど!」「目次にもこの本を授業でどう使うかが詳しく書かれていて、たとえばこの章とこの章は必須、この章とこの章は選択でいいよとか」「たしかに書かれてました」「日本だったら単位落とす学生が続出しそうですけど😆」

「加算器もハーフアダーとフルアダーが登場したり、マルチプレクサもあったり」「半加算器と全加算器ですねわかります」「表紙にもあるようにハードウェア寄りの話も結構登場しますし」「さらっと読める部分は本当にさらっと読めますけど、込み入っている部分は相当集中しないと読み進められない本」

「もうひとつのヘネパタは1万9000円とかするのか😳」「そっちは買ってません」「ヘネパタはまだ読んでないな〜」「パタヘネとヘネパタ、つい取り違えそうになっちゃうんですが、自分が買ったのはパタヘネ(コンピュータの構成と設計)の方でした😅」「ヘネパタはコンピュータ・アーキテクチャですね」

「やはりパタヘネはいい本: OSといえばタネンバウム本↓と言われるのと同じように、コンピュータアーキテクチャ方面ならパタヘネやヘネパタが定番として挙げられる教科書ですね」「買ったパタヘネちらっと開いてみたら、せ…せやなとしか言いようがない感じ😅」「上から順に読もうとすると挫折しやすいので、目次で当たりをつけてから読むといいと思います」

参考: アンドリュー・タネンバウム - Wikipedia

Gitでデフォルトのmasterブランチを別の名前にできるようになった


つっつきボイス:「Gitの新しいバージョンでmasterというブランチ名を設定で変えられるようになったそうです↓」「前はmasterという名前がハードコードされてたとは😳」「新しいプロジェクトからぼちぼち使うことになるかな」

$ git config --global init.defaultBranch main

「これをやるにはGitをアップデートしないといけなくなりますけど、古いGitを使ってる人って意外にいるんですよね」「あ、そうかも」

「そういえばブランチ名変更を強制じゃなくて選択可能にしたところにGitの良心を感じたってbabaさんが胸をなでおろしてました」「そりゃGitがデフォルトブランチ名を強制変更したらあちこちで火を吹いてぶっ壊れますよ😆」

その他OS・ツール

つっつきボイス:「このio_uringというのはLinuxのかなり新しいI/Oで、非同期に強いそうです」「Linuxは新しいインターフェイスをちょくちょく増やしてますね」「いくつかの言語がこのio_uringを取り入れようとしてるみたいです」

「今日ちょうど昼の社内勉強会でLinux入門をやったときにも少し話したんですけど、OSのシステムコールがサポートしていないと実現できない機能というものがあって、まさにこのio_uringがそういうものですね」「うんうん」「OSのシステムコールが拡張されると今まで書けなかったコードが書けるようになったり」「最近はマルチコアが当たり前になってますし、Dockerへの集約も進んでいるので、こういう非同期周りの重要性は以前にも増して上がってくるでしょうね」


「ruby-jp Slackで見かけたツイートです」「Rubyが動かないレベルってマジで…?」「CRubyはまだ厳しいでしょうね: Rosettaもありますけど完成度はそこまで高くなさそうですし」

参考: Rosetta - Wikipedia

その他

Mac OS 8もElectronで

felixrieseberg/macintosh.js - GitHub

felixrieseberg/windows95 - GitHub


つっつきボイス:「Mac OS 8のライセンスってもう切れてるんだっけ?」「私もわからなくって」「その下のWIndows 95の方が自分的に萌えるので後で調べてみようっと」「95エミュレータのREADMEに『Doomは動くのか: はい』ってあるあたりがワカッテラッシャル」

参考: Mac OS 8 - Wikipedia

「OS 8はさすがに触ったことないかな〜」「OS 8って97年ですか!」「完全モノクロだったMac OSの5ぐらいからです👴」「漢字Talkからだったかも」「それ何ですか?」「当時の日本ではMac OSが漢字Talkっていう名前だったんですよ」「漢字を表示するのにえらい苦労してましたね」「やべえTigerからなので何もわからないです〜」「もう知らなくていい知識😆」

参考: 漢字Talk - Wikipedia

「漢字TalkってOSの名前なんですか!」「たしかにOSの名前っぽくないですよね、アプリっぽいというか」「それで言うと超漢字もOSっぽくないですし」「かな漢字変換ソフトかと思っちゃいます」(以下SimCityやDoomの話など延々)

参考: 超漢字 - Wikipedia

Qiitaのエンジニア白書2020


つっつきボイス:「名前とか入力するとダウンロードできました」「この種のアンケートで定番の、今やってる言語とかこれからやりたい言語とかもありますね」「母集団を見ると回答者のうちエンジニアが2,334名でエンジニア未経験614名って未経験多くない?」「年収のところを見たらGo言語は収入が高いとか何とか」「そうかな〜?」「それってCOBOLやってる人の収入が高いみたいにエンジニアの絶対数が少ないからだったりして😆」(以下延々)

番外

5次元


つっつきボイス:「これはすごく難しそうだけど面白そうですよね」「発想は面白そうだけどゲーム性がどうなのかはやってみないとな〜」「UIの使いやすさとかプレイヤーが理解できるのかとか、そこですよね」「実はここをこうすると必ず勝てるとか😆」「チート😆」「SFとかアニメの小道具だったらかなりいい感じですよね」

「そういえば米国の「ビッグバン★セオリー」というドラマ↓にも「4D Chess」が登場していたんですね」「このドラマも随分前からやってるけどシーズン11もあるのか」「絵に描いたようなこじらせ系ギークが登場するヤツ」

参考: 4D Chess / 4次元チェス
参考: ビッグバン★セオリー/ギークなボクらの恋愛法則 - Wikipedia


後編は以上です。

バックナンバー(2020年度第3四半期)

週刊Railsウォッチ(20200803前編)書籍『パーフェクトRuby on Rails』増補改訂版、マルチDBで抽象クラスをscaffold生成、GitLabがPumaに乗り換えほか

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

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

Ruby 公式ニュース

Ruby Weekly

StatusCode Weekly

statuscode_weekly_banner


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。