週刊Railsウォッチ(20191008後編)Ruby 2.7のInteger#[]でバイナリチェック、rubyzip gemは強力、13KBのJavaScriptゲームほか

こんにちは、hachi8833です。今夜のノーベル賞は物理学賞ですね。

  • 各記事冒頭には⚓でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • 毎月第一木曜日に「公開つっつき会」を開催しています: お気軽にご応募ください

今回も第15回公開つっつき会を元にお送りします。

Ruby

Ruby 2.7でInteger#[]にrangeを扱う機能が追加(Ruby Weeklyより)

訂正(2019/10/09): 見出しに「にrangeを扱う機能」を追加しました🙇。

# 同記事より
# 77の2進数値
> 0b01001101
#=> 77
# 3の2進数値
> 0b0011
#=> 3
# range (2..5)を引数として渡す
# 位置2(値は1)から位置5(値は0)までを選択するので値は0b0011になる
> 0b01001101[2..5]
#=> 3
> 0b01001101[2...6] == 0b0011
#=> true
> 0b01001101[2, 4] == 0b0011
#=> true

つっつきボイス:「これちょっとスゴイかも」「0b01001101[2..5]だと、2進数の(最上位ビットが0桁目として)2桁目から5桁目、つまり0011(10進数の3)を切り出した…ってこと?!」「そこまでするか?😳」「なるほど、rangeで使うかどうかはともかくとしても、プロトコルヘッダーとかで特定の桁だけ取り出してフラグを確認したいということはあるかもですね」「それならやりたい😋」「気持ちはワカル😆」「他に使いみち思いつかないし😆」

「取り出しのみみたいですけど、代入できたらさらにコワい😇」「誰か作りそうではありますけど😆」

参考: Feature #8842: Integer#[] with range - Ruby master - Ruby Issue Tracking System

後でissueを見ると、(n >> 2) & 0xf == 0x3みたいなビット判定をRubyらしくやりたいということだそうです。

# #8842より
if n[2, 4] == 0x3
  ...
end

RubyでVisitorパターンを使ってテンプレートレンダリングしてみた(Ruby Weeklyより)


同記事より

参考: Visitor パターン - Wikipedia


つっつきボイス:「Railsのテンプレートレンダリングも元はVisitor的な設計思想だったんじゃないかしら🤔」「パーシャルをたどっていくあたりとかVisitorっぽいし」

# 同記事より
  class Interpreter
    attr_reader :root, :environment

    def self.render(root, environment = {})
      new(root, environment).render
    end

    def initialize(root, environment = {})
      @root = root
      @environment = environment
    end

    def render
      visit(root)
    end

    def visit(node)
      # Process node
    end
  end
end

GoF本的な書き方とは違うかな😆」「Visitorパターンはメソッド呼び出しが深くなるから重くなりがちですけど☺️」


同記事より

rubyzip: zipライブラリ(Ruby Weeklyより)


つっつきボイス:「おrubyzip出たな〜😆」「おぉ?」「いえ実はですね、とってもよく似た名前のziprubyというのもあるんですよ🤣」「え!?😳」「そう、紛らわしいの😢」「間違えてziprubyを入れると大変😇」「rubyzipはちゃんとメンテされてますが、ziprubyはずっとメンテされてない🏛」「たしかにziprubyは★ゼロ」「しかもziprubyは既存の何かのライブラリと名前空間がかぶってて、入れると壊れたりします😭」

「rubyzipが正解ということですね😋」「というわけで、★の数はちゃんと確認しましょうね😋」「教訓教訓」「rubyzipはいろいろ細かく指定してzipが作れるんですよ😋: 非圧縮のzipを作るとか↓」「ほぉ〜!😍」

# rubyzip/rubyzipより
    require 'zipruby'

    Zip::Archive.open('filename.zip') do |ar|
      n = ar.num_files # number of entries

      n.times do |i|
        entry_name = ar.get_name(i) # get entry name from archive

        # open entry
        ar.fopen(entry_name) do |f| # or ar.fopen(i) do |f|
          name = f.name           # name of the file
          size = f.size           # size of file (uncompressed)
          comp_size = f.comp_size # size of file (compressed)

          content = f.read # read entry content
        end
      end

      # Zip::Archive includes Enumerable
      entry_names = ar.map do |f|
        f.name
      end
    end

「そういえばEPUBパッケージもZipされていたな↓」「こういう細かい指定をやりたいときにrubyzipは便利👍」

参考: EPUBパッケージ方法

ファイル mimetype を一つ上の階層(フォルダ ebook の外側)に、 -0 で圧縮せず、-X でZIPヘッダにはextra fieldを付かない(ファイル属性を付けない)で ZIPコンテナ ebook.epub として保存する。
上記事より

「今回rubyzipを取り上げたのは、ちょっと前にruby-jp Slackで以下の記事↓を見かけたのがきっかけでした」「お〜なるほど、例の『zipのヘッダを改ざんして展開時にクソデカメモリを喰わせる』zip bomb攻撃💣」「前のウォッチで教えていただいたヤツですね(ウォッチ20190723)」

RuboCop作者のミニインタビュー(Ruby Weeklyより)

つっつきボイス:「最近のRuby Weeklyは下の方にtipsとかインタビューが載っていることが増えているんですが、RuboCop作者のBozhidar Batsovさんのミニインタビューがちょっと面白かったので😋」「どれどれ👀」

以下は抜粋です。


# rubocopの#7336より
# 後置のif/unlessでの代入は特殊
# 以下は実行すると"undefined local variable or method `a' for main:Object"エラーで終了
puts a if (a = @x)

# スコープ内に置くには事前の代入が必要
a = nil
puts a if (a = @x)

  • Q: (いい意味で)一番変わり者のRubyistは?

「『いい意味でああはなりたくない』ということかしら😆」「😆」


「数値の桁区切りで_を使おうとかじゃなくて、使うなと?!」「どして?」「『アンスコの桁区切りは一般的でない』『数値の桁区切りはカンマが常識』という主張みたい」「でもヨーロッパだと桁区切りがドット.で小数点がカンマ,のところもありますよね?」「そうそう😆、ついでにフランスだと桁区切りがnbspのスペースになることありますし🇫🇷」「少なくともPythonも数値の桁区切りに_使えますし😆」

参考: ノーブレークスペース(nbsp) - Wikipedia
参考: エンジニア・Webデザイナー必読: アプリケーションを国際化・多言語展開する前に知っておくべきこと - Qiita

2,345,678.01 # 日本や米国など
2.345.678,01 # ドイツなど
2 345 678,01 # フランス

「どうやら『アンスコは変数に使うべきだから、数値に使うと変数と紛らわしい』という主張なのか😳」「そうかなぁ〜?😅」「この人にとってはそうらしい」「まあアンスコで2桁ずつ区切ったりしたら本当に紛らわしいですけど☺️」「ともあれ、カルチャーを越えて安心して使えそうなのはアンスコかな〜」

桁区切りと日付の地域差

「そういえば日本だとある時期まで桁区切りを4桁ずつにしてましたよね?」「私は小学校でそう習いました😆」「3桁で習いましたけど😆」「漢数字だと万のところで区切りたいから4桁区切りが都合良かったんでしょうね」「日本にサウザンドとかミリオンとか英語表記が入ってきて整合しなくなったから3桁区切りが主流になったのかも?」

参考: 3桁区切りか、4桁区切りか - 困った時のメモ代わり

「数値の区切りで思い出しましたけど、日付のフォーマットが地域ごとに違ってるのもエグいですよね😇: こんなエントリ見つけましたし↓」「何という入り乱れ方!」「組み合わせのほとんどを制覇してそう😆」「Yだけは真ん中に来ないけど😆」「国境エリアに住んでる人とかどうしてるんだろう😆」「ほんまかいなという気持ちになれる☺️」「YMDってメジャーじゃないんだな〜🤔」「GreyにいたってはMDYとYMDとDMYが3つ入り乱れてるし🤣」「この辺はどこの国の植民地だったかが影響してるのかも🤔」「BlueでDMYとMDYが入り混じってるのが一番つらそう😭」「Blueの国のラインナップを見るとさもありなんという感じ😆」

参考: Date format by country - Wikipedia


Wikipediaより

「あと中国だと曜日を星期一みたいに数字で表しますね」「この間読んだ漫画で、ロシアでは血液型を数字で表すと知ってびっくりしました😳」

参考: 中国語の曜日と日付
参考: ロシアンスタイル│ロシアの総合情報ポータル ぱるぱるロシア

日本では血液型はA・B・O・ABと表記されますが、ロシアではこのようには表記されません。ロシアでは血液型をⅠ型(O型)、Ⅱ型(A型)、Ⅲ型(B型)、ⅳ型(AB型)と表記します。
privet.jpより

「Blood typeでググったらこんなコンパチビリティテーブル↓が😆」「😆」「こうしてみるとO-の互換性高いな〜」「AB+は他の誰にも血をあげられないという」

参考: Blood type - Wikipedia


Wikipediaより

その他Ruby

DB

さまざまなデータベースを比較してみた(DB Weeklyより)

見出し:

  • レガシーデータベース
    • フラットファイルデータベース
    • Unix系の/etc/passwd
    • 階層型データベース
    • ネットワークデータベース
  • リレーショナルデータベース
  • NoSQLデータベース
    • キーバリューデータベース
    • ドキュメントデータベース
    • グラフデータベース
    • カラムファミリーデータベース
  • NewSQLデータベース

つっつきボイス:「用途に合わせて進化するさまざまなデータベースを比較するという記事ですね」「database typesを一瞬データベースの型かと思っちゃいました😅」「それはdata typesの方☺️」


レガシーデータベースは現代的なシステムにつながる道、と」「paving?」「paveはたしか『舗装する』でした」

/etc/passwdもデータベース?!」「これもデータベースです😎」


「DNSやLDAPも階層型データベース↓というのは、言われてみればたしかに」「DNSは分散型でもあるし」「ファイルシステムをデータベースと呼ぶのはやや抵抗あるかも😆」「この記事は例を見るのが早い感じですね☺️」

階層型データベースの例:

  • ファイルシステム
  • DNS
  • LDAPディレクトリ

「ネットワークデータベースは馴染みないかな〜」「マルチプルペアレントができたりすると」「そういうのをネットワークデータベースと呼ぶならそうなんでしょうね😆」「ディレクトリを階層型データベースと呼ぶなら😆」

参考: ネットワーク型データモデル - Wikipedia

一方、ネットワーク型データモデルでは各レコードは任意の個数の親レコードと子レコードを持つことができ、ラティス構造を形成する。
ネットワーク型データモデルの主要な利点は、階層型データモデルに比較して、各実体の関係をより自然に表現できる点であった。このモデルは広く実装され使用されたが、2つの理由により支配的手法とはならなかった。第一にIBMが IMS や DL/I といった既存の製品で階層型データモデルに固執したことが挙げられる。第二に関係モデルの台頭がある。
Wikipediaより


同記事より

ネットワークデータベース型の例:

「ネットワークデータベースの現代的な例を見つけるのは難しいって記事にありますね😆」「だからイメージ掴みづらいのか😆」「こういうのはRDBでも同じようなことやれますし☺️」


リレーショナルデータベースはもうお馴染みのヤツ☺️」

リレーショナルデータベースの例:

  • MySQL
  • MariaDB
  • PostgreSQL
  • SQLite

「次はNoSQLデータベース」「キーバリューデータベースはそれこそハッシュがそのまんまキーバリューストアですし😆」「Redisがキーバリューデータベースの例に入ってるのはちょい納得いかないかな〜😆」「Redisはもっと強い😆」「Redisは最早単なるキーバリューストアじゃないし」

キーバリューデータベースの例:

  • Redis
  • memcached
  • etcd

ドキュメントデータベースの例:

  • MongoDB
  • RethinkDB
  • Couchbase

グラフデータベースの例:

  • Neo4j
  • janusGraph
  • Dgraph

「カラムファミリーデータベースもよくわからん😆」「Cassandraってこれに分類されるんですね😳」「キーがあってその下に任意の項目があるあたり↓とか、ちょっとMongoDBっぽい印象?🤔」


同記事より

カラムファミリーデータベースの例:

「お、AWSのDynamoDBもカラムファミリーデータベースなのか↓: よっしゃDynamoDBならわかる😋」「なるほど!😀」「DynamoDBはまさに上の図↑みたいな感じですね☺️: カラムファミリー(Fruit)が1個のDBになっていて、Keysのところにあるappleとかgrapeとかがそれぞれ1個の行(row)になり、プライマリキーは1個しか持てない、そしてDynamoDBの場合はグローバルセカンダリインデックスというのも与えられます👍」「おぉ〜」

参考: NoSQL_Dist - Column DB.pdf

「1個のキーの下に異なるキーバリューをぶら下げられるということですか?」「そう、つまりスキーマがない」「なるほど!」「こうすることでデータを柔軟に持てるし、あとこの構造だと分散がしやすいんだろうと思います☺️: 例に上がっているHBaseなんかもそうですけど大規模に多重分散できる💪」

参考: Amazon DynamoDB(マネージド NoSQL データベース)| AWS
参考: グローバルセカンダリインデックス - Amazon DynamoDB


hbase.apache.orgより


「最後のNewSQLデータベースは、NoSQLのつらいところを何とかするために出現したとかそういう感じ」「知らないものだらけ😅」「使ったことない😆」「CockroachDBが入ってますね😳」

NewSQLデータベースの例:

  • MemSQL
  • VoltDB
  • Spanner
  • Calvin
  • CockroachDB
  • FaunaDB
  • yugabyteDB

「そうそう、CAP定理ってあった↓」「Wikipediaを見ると、分散環境は一貫性と可用性と分断耐性にトレードオフの関係があるんですね😳」「3つのうち2つまでしか保証できないというヤツ☺️」「どんなシステムでも1つは諦めないといけない」

参考: CAP定理 - Wikipedia


「なかなか面白い記事👍」「全部説明するとなるとこっちも勉強必要ですね😆」

その他DB

今月のWeb+DB Pressの「RDBMS徹底比較」もいい記事でした😋。

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

GKEのロードバランサーが正式リリース(Publickeyより)

参考: コンテナ ネイティブの負荷分散を使用する  |  Kubernetes Engine のドキュメント  |  Google Cloud


つっつきボイス:「この図↓で言うと、従来(上)だとVM間でルーティングしていたけど新しい方(下)ではそういう無駄がなくなったのね😋」「賢いスイッチ的な」


publickey1.jpより

JavaScript

サイズ13KBのJSゲーム(JavaScript Weeklyより)


つっつきボイス:「ゲーム方面はよくわからないんですけど😅、このVoidcallというストラテジーゲームはJavaScriptでわずか13KBで書かれてるそうで、記事はそのメイキングオブです」「お❤️」

  • ゲームサイト: VOIDCALL(注意: 音が出ます)

「今どきのゲームらしく、ステージ生成とか3Dキャラクターモデリングなんかもやってて知見が炸裂してる感💪」「キャラクターにテクスチャを貼り付けるとこうなる↓」


同記事より

「そういえばその名もjs13kGamesっていうゲーム開発コンペサイト↓がありますね」「すごい名前😅」「文字通り13KBでJSゲームを作ると」「メイキング記事の冒頭にもそのリンクある!」「今どきはそういう縛りで戦ってるんですね😳」「聞いたことあったかも」


js13kgames.comより

「データも含めてこのサイズですし」「グラフィック系のカンファレンスとかコンテストなんかでも、こんなふうにソースコードが異様に小さいのにレンダリングされる絵が半端なく精密でスゴいのが飛び出してきたりしますね〜」「スゴすぎてもう見当付かない😅」

「メイキング記事には『半端ないスパゲッティコード』↓とありますし😆」「そりゃそうなる😆」「アイラブスパゲッティ😆」

「そしてminifyしたら11KBまで縮まった!↓」「やった🎉」「ソースもGitHubにちゃんとあるし」


同記事より


(忘れた頃に)「おぉ〜、このゲームのタブを開きっぱなしにしてたらいつの間にか失敗して終了してた😆」「😆」

JSツールがいろいろ残念な理由(JavaScript Weeklyより)

見出しの大意:

  • JSの設計はビジネスに耐えうるツールやアプリを作るためではなかった
  • コミュニティでかすぎ
  • 目標もゴールポストも移動してる
  • ボトムアップの世界につき責任者不在
  • ツールのオーナーシップを握れない
  • ファンディング
  • JSツールが全部ダメというわけではない

つっつきボイス:「公開時にはもう少しマシな日本語見出しにしようかなと😆」「まあ元が元ですし😆」

「最初のJSは10日で作られたって😆」「ホントだ😳」「プロトタイプを10日で作ったのね」「最初はLiveScriptという名前だったのがNetscape Navigator 2.0ベータ3でJavaScriptという名前に変えられたとかいろいろ知らね〜😆」

「JSのユーザーが多すぎるというのもそうですね🤔」

「moving goalposts?」「ゴールに到着した頃にゴールポストが動かされちゃうという😆」「『JSライブラリがブラウザでもNodeでも同じように動くべきかどうかについて私たちは合意に達しない』、わかる〜😭」

参考: ムービング・ゴールポスト - Wikipedia

「『JSツールはボトムアップ型で作られるから誰も責任を取らない』😆」

「『JSツールはもろい抽象化の上に積み重ねられてるのがアカン』😆」「semverって?」「あ、セマンティックバージョニング(semantic versioning)か」「英語圏だとよくsemverって略してるみたいです」

参考: A simple guide to semantic versioning

「まあ記事からいろいろ気持ちは伝わってくるけど、でも使わざるを得ないのがJS😆」「たしかに😆」

「最後の『JSもそこまで捨てたもんじゃない』にこんなチャートが↓」「『JSアプリの構築は今も複雑化してるか?』というアンケートの回答ですね」「agree系が微減で、disagree系が微増とは😆」「以前よりはマシになったと」「ちょろいJSアプリをyarnで作るだけで大量に入ってくるのがもう当たり前になっちゃったからこういう感想になったのかも🤔」「諦めの境地😆」


同記事より

記事の末尾でも自分で自分にツッコんでますね。

CSS/HTML/フロントエンド/テスト

WindowsからiOS Safariのコンソールを使う


同記事より


つっつきボイス:「BPS社内Slackでアプリチームの人がこれを貼ってました」「へぇ〜、Windows 10からiOSのSafariのコンソールをつっつけるんだ」「もうSafari使ってない😆」

言語・ツール

プログラミング言語ブログ


つっつきボイス:「重症のプログラミング言語マニアと思われるサイトなんですけど、よく知らないものも含めてすごい量のプログラミング言語が並んでたので😳」「たしかに半端ない量」「しかも触ってみた寸評もいろいろ書いてあって楽しめます😋」「TODOが付いてるのはこれから書くんでしょうね😆」

「Hotelって名前の言語あるし↓😆」「ホテル😆」

「jq↓って言語?😆」「jqってコマンドラインでJSONを処理できるヤツですよね: ちょっと癖あるけど速くて好きです😋」

  • サイト: jq


stedolan.github.io/jqより

「それにしてもよくこんなにたくさん触って覚えてられるな〜😳」「Matzと盛り上がれそう😋」

なおRubyについては「先祖がSmalltalkなので親しみを感じられる」とありました。TypeScriptとかメジャーなものが意外にありませんでした。

qmailの設計


つっつきボイス:「エンジニア滑らない話😆」「qmailってあったな〜」「なつかし〜👴」「90年代後半ぐらいに出てきたんでしたっけ」

参考: qmail - Wikipedia

「たしか当時使われていたSendmailで脆弱性がめちゃくちゃ出まくってて『オレが絶対バグのないMTAを作っちゃる』って作ったのがqmailだった覚えが😆」「😆」「しかもqmailが更新されないのも『バグがないからだ』って🤣」「それは🤣」「でもたしかにSendmailはよく落ちてたけどqmailは安定してましたね☺️」

参考: Sendmail - Wikipedia


後ではてブでもバズっていました↓。

参考: [B! qmail] 他人のコードや設計を見て1番これはあり得ないだろと思う実装はありますか? - Quora

その他言語

その他

睡眠と成績


つっつきボイス:「やっぱり睡眠大事😴」「運動との相関を見つけようとしたら睡眠との相関しか見つからなかったというのが本当っぽい😆」

その他のその他

参考: pdf: DEEP LEARNING FOR SYMBOLIC MATHEMATICS


openreview.netより


つっつきボイス:「AIで方程式を木構造にして解くんだそうです」「プログラミングの練習問題で逆ポーランド記法で入力を渡す電卓プログラムがよく出されますけど、それくらいでしか見たことないなー😆」

参考: ポーランド記法 - Wikipedia

番外

神経の信号からニューロンのつながりを推定


つっつきボイス:「いわゆる信号処理の分野だと思うんですけど、これちょっと凄い😳」「脳をかっさばなくてもニューロンのつながりを調べられるようになったら検査とかに応用されそう☺️」「この方面が今後伸びそうな予感してます😋」


後半は以上です。

終了後はこの動画を環境映像として流しながらの親睦会となりました🍻🍕。ご参加ありがとうございます!

バックナンバー(2019年度第4四半期)

週刊Railsウォッチ(20191007前編)Ruby 2.6.5でセキュリティ修正、Arel.sqlがstable APIに、Puma 4.2、RailsのDomain ObjectとService Objectほか

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

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

Ruby Weekly

RubyFlow

160928_1638_XvIP4h

Publickey

publickey_banner_captured

DB Weekly

db_weekly_banner

JavaScript Weekly

javascriptweekly_logo_captured

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の監修および半分程度を翻訳、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れて更新翻訳中。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好きで、Goで書かれたRubyライクなGoby言語のメンテナーでもある。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

開発
Ruby 2.7.0-preview2がリリース

2019年10月23日

夏のTechRachoフェア2019

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ