- Ruby / Rails関連
週刊Railsウォッチ(20200128後編)もう一つのgemマネージャgel、”Did you mean”の仕組みを追う、DXOpalでブラウザゲームほか
こんにちは、hachi8833です。
- 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
- 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
- 毎月第一木曜日に「公開つっつき会」を開催しています: お気軽にご応募ください
⚓お知らせ: 公開つっつき会2本立て
⚓その1: 週刊Railsウォッチ「第19回公開つっつき会」(無料)
いよいよ第19回を迎えた公開つっつき会は、来月2月6日(木)19:30〜よりBPS株式会社Pubスペースにて開催いたします。
週刊Railsウォッチの記事やここだけの話にいち早く触れられるチャンス!発言・質問も自由です。皆さまのお気軽なご参加をお待ちしております。
⚓臨時のお知らせ: 福岡でのリモート公開つっつき会は「延期」いたします(Wingdoor@福岡)
今週木曜に予定されていた福岡での公開リモートつっつき会は延期となりました🙇。
⚓Ruby
⚓DXOpal: Rubyでブラウザゲーム
つっつきボイス:「OpalをベースにRubyでブラウザゲームを作れるライブラリだそうです」「お〜Opal頑張るな〜😳」
「記事で紹介されているるびまのDXOpal記事↓は2018年のなので割と最近ですね」「Opalでここまでやるとは😆」「ゲームづくり初心者へのお題にするのはキツいでしょうか?」「Opalを使う時点でRubyからトランスパイルされたJavaScriptと戦わないといけなくなるから、入門者には相当ハードル高いのでは😆」
参考: るびま0057: Rubyで始めるゲームプログラミング - DXOpal編 -
⚓RubyのRationalとBigDecimalのバグ
# #16518より
> 1 == BigDecimal(1)
=> true
> Rational(1, 1) == Rational(BigDecimal(1), 1)
=> true
> Rational(1, 6) == Rational(BigDecimal(1), 6)
=> true
> Rational(1, 60) == Rational(BigDecimal(1), 60)
=> false
つっつきボイス:「これもst0012さんが見つけたRubyのバグです」「ああBPS社内Slackに貼ってあったヤツ: これは相当びっくりする謎挙動😆」「issueでも驚かれてますね」「どうしてこうなるのかマジわからない😆」「もともと以下のRails issue↓を追っていて見つけたんだそうです」「DateTimeの丸めで起きるバグとか踏みたくない〜😅」「1秒ずれてる...」
# #38041より
# Rails 5.2.4.1: OK
"2019-12-19 10:00".to_datetime - BigDecimal(1).hour
=> Thu, 19 Dec 2019 09:00:00 +0000
# OK
# Rails 6.0.2.1: WRONG
"2019-12-19 10:00".to_datetime - BigDecimal(1).hour
=> Thu, 19 Dec 2019 08:59:59 +0000
⚓gel: もうひとつのgemマネージャ
つっつきボイス:「先週のウォッチで紹介した@hsbtさんのスライド↑で知りました」「アイコン溶けてる🍨」「rubygemsにもbundlerにも依存せずにbundlerと同じような感じでやれるようで、スライドにもこのgemから学ぶべきとありますね」「まあ今はbundlerとrubygemsが統合される流れになってますけど」「現状だとメンテが大変という話が先週もありましたね(ウォッチ20200121)」「この辺は今後も進化し続けるでしょうし、新しいものを取り入れていくのがRubyやRailsの文化ですし、いいんじゃないでしょうか☺️」
⚓その他Ruby
# 同記事より
Traceback (most recent call last):
fun.rb:5:in `<main>': undefined local variable or method
`greeet' for main:Object (NameError)
Did you mean? greet
つっつきボイス:「Rubyの"Did you mean"の仕組みを追った長めの記事です」「あそこはなかなか込み入ってます😆」「考えてみたら結構すごいことやってるんですよね」「アルゴリズムとかいろいろ面白いですし: 推測が外れることもありますけど😆」
「最近だとfishみたいな新し目のシェルにもDid you mean的な機能あったりしますし」「そういえば」
参考: 環境構築:ユーザフレンドリーで補完機能の強力なfishへ移行(Login shellをbashからfishへ移行)
⚓DB
⚓PostgreSQL全文検索のエッジケース(DB Weeklyより)
-- 同記事より
CREATE FUNCTION skills_tsv_update_trigger() RETURNS trigger AS $$
begin
new.tsv :=
to_tsvector('pg_catalog.english', COALESCE(new.title, ''))
return new;
end
$$ LANGUAGE plpgsql;
つっつきボイス:「to_tsvector
っていう関数で生成してるんですね」「text search vectorなのか」
- PostgreSQL 11ドキュメント: 12.3. テキスト検索の制御
「たとえばroofingという語はあるのにroofiで全文検索すると何も出てこないという問題だそうです」「JSON extractとかでもよくありそうな、使い方が実は違ってる的な問題?😆」「英語で活用される部分がこぼれちゃったとか?」「'pg_catalog.english'
とかあるし、そんな雰囲気」「バイナリにしないといけないとか?」「でもそれだと自然言語検索になりませんし」「それもそうですね」
-- 同記事より
SELECT * FROM skills
WHERE
tsv @@ to_tsquery('pg_catalog.english', 'roofi:*')
-- no records found
- PostgreSQL 11ドキュメント: 9.15. JSON関数と演算子
「結論としては'pg_catalog.simple'
についてもto_tsvector
する行を足して結合したらそれっぽく解決できた↓」「なるほど」「英語の自然言語検索って自分たちはめったに実装しないからな〜😆」
-- 同記事より
CREATE FUNCTION skills_tsv_update_trigger() RETURNS trigger AS $$
begin
new.tsv :=
to_tsvector('pg_catalog.english', COALESCE(new.title, '')) ||
to_tsvector('pg_catalog.simple', COALESCE(new.title, ''))
return new;
end
$$ LANGUAGE plpgsql;
「この記事書いた人は全文検索使いまくってるそうですけど、SQLのRDBMSで全文検索ってあんまりやらない印象ありますね」「全文検索はSQLの標準機能じゃないので、MySQLでもぽすぐれでもたいてい拡張を使わないとできませんね🧐」
⚓tbls: データベースの仕様をMarkdownで一気に出力(DB Weeklyより)
試しに動かしてみました
tbls doc postgres://hachi8833:$DB_PASSWORD@localhost:5432/enno_development?sslmode=disable
dbdoc/README.md
dbdoc/ar_internal_metadata.md
dbdoc/patterns.md
dbdoc/schema_migrations.md
dbdoc/spell_checks.md
dbdoc/import.patterns.md
つっつきボイス:「Graphvizっぽい画像かな: まあよくあるツールです😆」「でしたか😅」「いっぱいありますよ: Railsにもコマンドラインレベルならrails about
とかありますし☺️」「ツールのdependencyがやけに多いなと思ったら、BigQueryやらRedshifやらたくさんのデータベースに対応しているみたいですね」「まあRailsのSTI(Single Table Inheritance)とかはちゃんと図を出せなさそうな気がしますけど😆」「そうかも😅」「使うならCIとかで自動更新しないと古いのが残ったままでハマりの元になりそうですし☺️」
「Markdown形式の仕様書が求められるならこのツールでいいけど、日本だとだいたい例のA5:SQL Mk-2↓になりますよね😆(ウォッチ20181210)」「名前の覚えにくい例のツールですね😆」「何といってもExcel形式で生成されますし☺️」
参考: A5:SQL Mk-2 - フリーの汎用SQL開発ツール/ER図ツール .. 松原正和
⚓その他DB(DB Weeklyより)
つっつきボイス:「Microsoftの公式アカウントがぽすぐれ愛のYouTube動画を公開してるのが何とも😆」「最近のMicrosoftはSQL Serverにそんなにこだわってない感じですし」「ですね」「これはMicrosoft Igniteというイベントのスピーチらしい↓」「このイベント知らなかった😳」「ミートゥー😆」「ignite(点火)とnightをかけてるんでしょうね」
参考: Microsoft Ignite The Tour 2019-2020
⚓クラウド/コンテナ/インフラ/Linux/Serverless
⚓大阪がリージョン化へ(Publickeyより)
つっつきボイス:「まあ東京で仕事してたらあまり関係ありませんけど😆」「今までは公式のリージョンじゃなかったんですね」「非公式の大阪リージョンはありましたけど、今までは限定的だったのがついにここまで🎉」
「たしか大阪リージョンができたときはAZ(Availability Zone)が2つしかなくて、サービスも標準より少なかった覚えがあります☺️」「なるほど」「AWSのサイトで見るともう大阪使えるようになってますね↓: ap-northeast-3
か」「2はソウル」「できた順だからしょうがない😆」
⚓G SuiteアカウントでWindows 10にログイン(Publickeyより)
つっつきボイス:「これはちょっと色めき立ちますね❤️」「前にマイクロソフトがGoogleアカウントでWindowsやOffice 365にログインできるようになったニュースがありましたけど(ウォッチ20180910)、これはGoogle側の対応なんですね」「この辺は技術的にはSAML↓か何かで共有とかすればやれると思います」「さむるですか」
参考: Security Assertion Markup Language - Wikipedia
⚓その他インフラ
つっつきボイス:「ロボット業界ニュースに出ていたドコモ6Gの記事です」「まあホワイトペーパーなので一種夢のお絵かきと思っておけば😆: でも2030年はそんなに遠い未来でもないか🤔」
「お、DOCOMO Open House↓でやってたのか」「このイベントは?」「ドコモは昔からこうやって未来のコンセプト動画をぶち上げることを数年おきにやっているんですよ☺️」「へ〜!」「近未来のインフラの姿とかをドラえもん的に描くヤツです📺: 当たってる予想もあればそうでないのもあったりして結構面白いですよ😋」「なるほど〜」「DOCOMOみたいな企業はニーズを作るところから手掛けるので☺️」
参考: DOCOMO Open House 2020 - ようこそ、5Gリアルワールドへ。そしてその先へ。 - -- 終了しました
⚓JavaScript
⚓ava: JSテストフレームワーク
- リポジトリ: avajs/ava at v3.0.0
参考: テストフレームワーク「ava」の基本的な使い方をまとめてみる。 - "BOKU"のITな日常
つっつきボイス:「avaは最近よく使われているみたいなんですけど、JavaのJが取れたみたいな感じですね😆」「単なるテストランナーだけじゃなくてテストスイートも入ってるみたい: ↓こういうハイライトはありがたいな〜😋」「おぉ」「必要そうなものはだいたい入っている感じかな: きっとvscode連携とかでみんな使うようになるんでしょうし😆」「でしょうね😆」
⚓きれいに書き直したJSコードがrevertされた理由(JavaScript Weeklyより)
- 元記事: Goodbye, Clean Code — Overreacted([JavaScript Weekly]
// 同記事より
let {top, bottom, left, right} = Directions;
function createHandle(directions) {
// 20 lines of code
}
let fourCorners = [
createHandle([top, left]),
createHandle([top, right]),
createHandle([bottom, left]),
createHandle([bottom, right]),
];
let fourSides = [
createHandle([top]),
createHandle([left]),
createHandle([right]),
createHandle([bottom]),
];
let twoSides = [
createHandle([left]),
createHandle([right]),
];
function createBox(shape, handles) {
// 20 lines of code
}
let Rectangle = createBox(Shapes.Rectangle, fourCorners);
let Oval = createBox(Shapes.Oval, fourSides);
let Header = createBox(Shapes.Rectangle, twoSides);
let TextBox = createBox(Shapes.Rectangle, fourCorners);
つっつきボイス:「きれいに書き直したら翌日『戻せ』と言われたんだそうです」「こういうのはプロジェクトでもときどき問題になりますね: 意味のない書き直しをされると時間も食われるし、アウトプットにもならないし、開発も進まないし😇」「記事の人も当時はせっかくDRYに書いたのにと思っていて、それがよくなかった理由を納得するのに数年かかったそうです😅」「たとえよかれと思ってやったとしても、レビュアーの工数も吸い取られるし、いいことないですよホント😢」「自分も気をつけないと😅」
⚓その他JS
- リポジトリ: uuidjs/uuid: Generate RFC-compliant UUIDs in JavaScript -- RFCに則ったUUIDジェネレータ(JavaScript Weeklyより)
// 同記事より
const uuidv3 = require('uuid/v3');
// ... using predefined DNS namespace (for domain names)
uuidv3('hello.example.com', uuidv3.DNS); // ⇨ '9125a8dc-52ee-365b-a5aa-81b0b3681cf6'
// ... using predefined URL namespace (for, well, URLs)
uuidv3('http://example.com/hello', uuidv3.URL); // ⇨ 'c6235813-3ba4-3801-ae84-e0a6ebb7d138'
// ... using a custom namespace
//
// Note: Custom namespaces should be a UUID string specific to your application!
// E.g. the one here was generated using this modules `uuid` CLI.
const MY_NAMESPACE = '1b671a64-40d5-491e-99b0-da01ff1f3341';
uuidv3('Hello, World!', MY_NAMESPACE); // ⇨ 'e8b5a51d-11c8-3310-a6ab-367563f20686'
つっつきボイス:「JSでUUID生成だそうです」「ID生成器は速度も重要な要素ですね☺️」「READMEにbut not this smallってあるのは何だろう?」「ああ、やりたいのはこういうスモールさじゃないぞ↓ということね😆」「😆」「UUID生成は自分で書きたくないな〜」
// https://gist.github.com/jed/982883#gistcomment-45186 より
function b(a){return a?(0|Math.random()*16).toString(16):(""+1e7+-1e3+-4e3+-8e3+-1e11).replace(/1|0/g,b)}
⚓CSS/HTML/フロントエンド/テスト
⚓Reporting API
つっつきボイス:「jxck.ioさんのReporting API記事です」「へぇ、Report-To
ヘッダーでReportingエンドポイントを外におけるのか」
# 同記事より
Report-To: {
"max_age": 36000,
"endpoints": [
{
"url": "https://reports.example.com/default-endpoint"
}
]
},
{
"group": "csp-endpoint",
"include_subdomains": true,
"max_age": 36000,
"endpoints": [
{
"url": "https://reports.example.com/csp-endpoint1",
"priority": 1,
"weight": 50
},
{
"url": "https://reports.example.com/csp-endpoint2",
"priority": 1,
"weight": 50
},
{
"url": "https://failover.example.com/csp-endpoint",
"priority": 2
}
]
}
「structured header(SH)も、ブラウザの機能が今後ますます増えていくことを考えたらこういうのは欲しいですね😋」「何かあったときにブラウザからレポートしてくれると」「deprecateされたAPIをブラウザが呼んだときに発生するDeprecation Reportも欲しいヤツ: deprecatedかどうかはブラウザからじゃないとわからないので」「おぉ」「Feature Policy Violationとかも流れてきてくれたら嬉しい😂」
参考: Switch reporting to Structured Headers · Issue #177 · w3c/reporting
// 同記事より
{
"type": "deprecation",
"url": "https://blog.jxck.io/entries/2018-05-15/webauthentication-api.html",
"body": {
"id": "ChromeLoadTimesWasAlternateProtocolAvailable",
"anticipatedRemoval": null,
"message": "chrome.loadTimes() is deprecated, instead use standardized API: nextHopProtocol in Navigation Timing 2. https://www.chromestatus.com/features/5637885046816768.",
"sourceFile": "chrome-extension://mpbpobfflnpcgagjijhmgnchggcjblin/content.js",
"lineNumber": 5,
"columnNumber": 19
}
}
{
"type": "deprecation",
"age": 27,
"url": "https://example.com/",
"user_agent": "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0",
"body": {
"id": "websql",
"anticipatedRemoval": "1/1/2020",
"message": "WebSQL is deprecated and will be removed in Chrome 97 around January 2020",
"sourceFile": "https://example.com/index.js",
"lineNumber": 1234,
"columnNumber": 42
}
}
「まだまだ仕様が安定していないのは今はしょうがない」「あとモニタリング系サービスがReportingをサポートするというアイデアもいいですね: ScoutやNew Relicのようなサービスがこれをサポートしたら端末ごとの情報収集とかもできますし😍」
⚓最近のフォトショ
つっつきボイス:「画像はリンク先で見ていただくとして、最近のプラグインのインテリジェントぶりがすごいですね😳」「へぇ〜、細かい髪の毛だけじゃなくて、自動車の窓の向こう側まで切り取るとか、アルファ値も処理してるっぽい」「窓ガラスの向こうがきれいに切り取られてますね😳」「こういうプラグインがあるということを知っておくのがとりあえず大事😆」
参考: アルファ値 (デジタル画像) - Wikipedia
⚓その他フロントエンド
仮想ブラウザ。WebRTC を使ってサーバで起動するブラウザの画面を転送。 #golang / “GitHub - nurdism/neko: A self hosted virtual browser (https://t.co/d3mjn0S6ef clone) that runs in docker.” https://t.co/wNBzxM8UZI
— mattn (@mattn_jp) January 18, 2020
これすごい良く出来てる。コードみたけど想像以上にしっかり作られていた。プロダクションだったりするのでは? https://t.co/v3okhQnGds
— V (@voluntas) January 18, 2020
つっつきボイス:「とりあえずネコがカワイイ😼」「(デモ画像を見ながら)まさにバーチャルブラウザか: Dockerイメージを起動するとlocalhostでリッスンして、その中で仮想ブラウザが動いてる」「あ〜そういうことですか!」「WebRTCでつないでくれるのね↓」
「nekoは何か既存のライブラリをうまく使ってるんだろうか🤔」「ツイートの続きを見るとPionというのがありますけどこれかな?」「PionはC++のライブラリでどことなくFirefoxっぽいけどよくわからん😆」
「個人開発のための Webサービス公開マニュアル」を出版することになったきっかけの話です。
書籍を出版することになったきっかけ - Crieit https://t.co/D6rK69ch9H #Crieit
— だら🎄サービスづくりひたすら (@dala00) January 19, 2020
つっつきボイス:「個人開発向けの本ということですけど、コードを書いた後のデプロイの解説が評判いいみたいです」「へ〜、こういうノウハウがまとまっているのはなかなか良さそう❤️」
「目次が見たいな」「Amazonにはスクショの目次しかありませんでした😇」「なるほど、デプロイだけで1章あるのか」「後半がまるまるデプロイですね: 買ってみちゃおうかな👍」「中身見ないとわからないけど、Google AnalyticsやCloudflareとか、あと運用の話が入ってるのはいいですね〜👍」「やった!」「あとはボリュームがどのぐらい充実してるかですね☺️」
「この辺は開発を長くやってればだいたいわかってくるかもしれませんけど」「インフラエンジニアとしてでしょうか?」「いや、開発者全員が知るべきですっ😆」
買いました😋。
⚓言語・ツール
⚓verona: マイクロソフトの研究用言語
Microsoft が研究で試作(https://t.co/GvWqZSFPwe)してる言語 Verona のコードを公開.C, C++ の代替を模索してるっぽくて,Concurrent Ownership という新しい並列モデルを採用してる | 'microsoft/verona: Research programming language for concurrent ownership' https://t.co/X68XMadOVt
— ドッグ (@Linda_pp) January 17, 2020
// 同リポジトリより
// x は隔離されたオブジェクトグラフ
var c = cown(x)
// cはxへのアクセスを調停するcown
// xへのダイレクトアクセスはここで失われる
when (var x = c)
{
// ここで名前xを用いてcown(c)の内部にアクセスする
Builtin.print("Hello\n")
}
Builtin.print("Goodbye\n")
つっつきボイス:「Concurrent Ownershipとかいう新しい概念の有効性を確認する目的で試作した言語らしいです」「Rustをフィーチャーした言語を作るみたいな話があったけどそれかな↓」「ああこれです」「見た感じ普通にプログラミング言語でしょうね☺️」
参考: マイクロソフト、「Rust」に基づくプログラミング言語プロジェクト「Project Verona」がGitHubに - ZDNet Japan
Microsoftは、Project Veronaを「リサーチプログラミング言語」だととらえており、オープンソース化によって、並行オーナーシップ(所有)というコンセプトについて探求したいと考えている学術分野の協力者を呼び込みたいと考えている。
japan.zdnet.comより
「ちなみにconcurrent ownershipはどうも米国の法律用語(不動産方面)をもじっているみたいで、ググるとそっちばかり出てきました」「所有者が同時に複数いるという点ではこれもまさにそれでしょうね: リソースの保護とか管理とか」
参考: Definition of a Concurrent Ownership - Real Estate
⚓その他言語
- 元記事: 日本語形態素解析の裏側を覗く!MeCab はどのように形態素解析しているか - クックパッド開発者ブログ
- イベント: PPL 2020: 第22回プログラミングおよびプログラミング言語ワークショップ
つっつきボイス:「ガチ理論寄りのワークショップだそうです」「日本ソフトウェア科学会で理論寄りは珍しいかも🤔」「今回の開催地は佐賀県だそうです」「まあこういうワークショップは『次はどこでやろうかな😋🍽🍱🍶』みたいなノリで運営されてたりしますけど😆」
つっつきボイス:「この記事読んだ気がすると思ったら2018年のですし😆」「ありゃ😅」
「QRコードは一応目で読もうと思えば読めないこともありませんね☺️: どの方向にスキャンするとか決まってるので」「今日の勉強会でメールのMIME multipartを手書きした話をちょっと思い出しました」「MIMEのmultipartデータはテキストエディタで誰でも作れますよ😆(lengthを合わせるとかは必要かもしれないけど)」「そうでしたか」「MIMEのmultipartは元々メールの仕様↓ですけど今はもうWebのフォーム送信とかあちこちで使われてますね☺️」「そういえばMIMEの略語ってこれでしたね」「MIMEは見てのとおりメールが元祖なのに、メールじゃないものにめっちゃ使われているという😆」
参考: RFC 2046 - Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types
⚓その他
⚓「インターネット電池社会」モデル
つっつきボイス:「元記事の誤植訂正でインターネット電池社会というコンソーシアムを知りました」「村井先生はこういうのを立ち上げるのが上手いですね😋」(以下延々)
⚓その他のその他
つっつきボイス:「オランダはあくまで通称😆」「オランダって呼んでるの日本ぐらい?」「オランダはもともと州の名前だったのが俗称の国名として使われたみたいで、言ってみれば日本を『関東』とか『本州』と呼ぶみたいなものかなと思って😆」「nl
ロケールには影響なさそうでよかった😆」
日本でもそうですね.酒を良く飲むのは中高年という印象になってきましたし,会食のときに飲まなくても何も言われなくなってきました.良い傾向.麻薬や覚醒剤等の危険ドラッグが禁止されている一方で,酒やタバコのような同じように危険な薬物が年齢制限以外は禁止されていないのも非合理的ですし.
— Yuta Kashino (@yutakashino) January 19, 2020
つっつきボイス:「日本ではストロングゼロが蔓延してますけど😆」「あれは本当にヤバいみたいですね」「500mlで売るのはヤバい」
⚓番外
⚓ここまで来たか
つっつきボイス:「葉脈の顕微鏡動画みたい🌿」「このスケールで観測できたのがスゴい😳: さすがに電子のサイズだと不確定性原理とかで無理かな😆」
後編は以上です。
バックナンバー(2020年度第1四半期)
週刊Railsウォッチ(20200127前編)Railsでキーワード引数warning退治始まる、ライブラリとフレームワークの違い、ShopifyのRails高速化記事ほか
- 20200121後編 RubyKaigi 2020受付開始、RubyGemsとBundlerの今後、ファイル同期ツールMutagenほか
- 20200120前編 福岡でも公開つっつき会、Railsのconnection_specification_nameでprimaryという名前が非推奨に、structure.sqlとschema.rbほか
- 20200115後編 Ruby 2.7関連情報、Bootstrap 5は今年前半リリースか、PostgreSQLでやってはいけないリストほか
- 20200114前編 config_forのbreaking change、Active Storage variantをDBでトラッキング、SprocketsとWebpackの違いほか
今週の主なニュースソース
ソースの表記されていない項目は独自ルート(TwitterやはてブやRSSやruby-jp Slackなど)です。