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

週刊Railsウォッチ(20200811山の日短縮版)RSpec Queueでパラレルテスト、カロリーメイトとRubyのコラボ、Rubyのcoercionほか

こんにちは、hachi8833です。昨日は山の日ということで短縮版でお送りします。

回答しそびれましたが、Ruby 2.7のirbがとてもよくなったので自分も最近pryを使わなくなってました。

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

Rails: 先週の改修(Rails公式ニュースより)

今回はchangelogの更新はありませんでした。

validates_inclusion_ofメソッドにeach_object:オプションを追加

特定の属性に対応する値が配列の場合、バリデーションでは指定のメンバーにその配列が含まれているかどうかをチェックする。:each_objectを使うと配列内の各オブジェクトが指定のメンバの中になければならないということを指定できる。
これは、たとえばデータベースカラムでarray: trueオプションを使っていて、指定の有効な値リストが配列のメンバーに含まれているかどうかを指定したい場合に有用。
変更前: features属性が["Bluetooth"]を含む配列の場合、以下のバリデーションは失敗する(["IR", "Bluetooth", "Wireless"].include?(["Bluetooth"])がfalseになるので)。

validates_inclusion_of :features, in: %w(IR Bluetooth Wireless)

変更後: 以下はパスする(featuresの各オブジェクトが指定のメンバーに含まれているかどうかが実際にチェックされるので)。

validates_inclusion_of :features, in: %w(IR Bluetooth Wireless), each_object: true

Railsに初めて投げたプルリクにつき、フィードバックは大歓迎です。
同PRより大意


つっつきボイス:「だいぶ昔のプルリクがマージされていました」「2015年って書いてますけど互換性とか大丈夫だったのかしら?」「さすがにgit rebaseとかやってるでしょうけど」

validates_inclusion_ofっていう書き方がそもそも古いですし: Rails 3ぐらいじゃなかったっけ?」「あ、もっと簡潔な書き方があるんですね」「もう随分前からvalidates :age, inclusion:みたいに書くのが普通です」「道理でvalidates_inclusion_ofって見覚えないと思った😆」

# api.rubyonrails.orgより
validates :terms, acceptance: true
validates :password, confirmation: true
validates :username, exclusion: { in: %w(admin superuser) }
validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create }
validates :age, inclusion: { in: 0..9 }
validates :first_name, length: { maximum: 30 }
validates :age, numericality: true
validates :username, presence: true

「このプルリクは、今までだと:featuresがstringならうまくいくんですけど、array of stringだと期待どおりに動かなかったのをeach_object: trueを指定することで動くようにしたということでしょうね」

# 変更前
validates_inclusion_of :features, in: %w(IR Bluetooth Wireless)

# 変更後
validates_inclusion_of :features, in: %w(IR Bluetooth Wireless), each_object: true

「それにしても5年越しのマージとは」「こんなに塩漬けにされてたのって何でだろ?」「改善内容はわかるけど、たぶんこれで困る人が少なかったからじゃないですかね」「必要なものなら色んな人が推すでしょうし」「これなら自分でバリデーター作れるでしょうし」「コメント見ると年に1度ぐらいレスやstaleタグが付けられてますね」「七夕みたい💫」「そして4日前にマージされたと」「初プルリクがついにマージ、お疲れさまです…」「これでRailsのプルリクも1個減りましたね」

マルチプルDBのdb:migrate:redoで名前を指定できるようになった

» bin/rails db:migrate:redo:secondary
== 20200728162820 CreateAnimals: reverting ====================================
-- drop_table(:animals)
   -> 0.0025s
== 20200728162820 CreateAnimals: reverted (0.0047s) ===========================

== 20200728162820 CreateAnimals: migrating ====================================
-- create_table(:animals)
   -> 0.0028s
== 20200728162820 CreateAnimals: migrated (0.0029s) ===========================

つっつきボイス:「ああマルチプルDBのdb:migrate:redoね」「これは?」「マルチプルDBのrakeタスクは指定先データベースの識別子を渡せるようになっているんですけど、redoで対応していなかったのを対応したんでしょうね」「redoの対応が漏れてたのか」

db:migrate:redoを開発で使う機会ってめったにないと思いません?」「自分もないな〜」「もちろん機能としては前からありますし、CIで使いたいときもありそうですけどね」

StiClass.allで暗黙のcreate_withを回避するようにした

現在は暗黙のcreate_withを使っても使わなくても、ensure_proper_typeによってsti_nameが設定されている。

      def initialize_internals_callback
        super
        ensure_proper_type
      end

      # Sets the attribute used for single table inheritance to this class name if this is not the
      # ActiveRecord::Base descendant.
      # Considering the hierarchy Reply < Message < ActiveRecord::Base, this makes it possible to
      # do Reply.new without having to set <tt>Reply[Reply.inheritance_column] = "Reply"</tt> yourself.
      # No such attribute would be set for objects of the Message class in that example.
      def ensure_proper_type
        klass = self.class
        if klass.finder_needs_type_condition?
          _write_attribute(klass.inheritance_column, klass.sti_name)
        end
      end

create_withtype_conditionを抑制したりオーバーライドするのが目的。type_conditionscope_for_createですべてのSTIサブクラス名の配列になるので、scope_for_createでは望ましい振る舞いにならず、find_sti_classが失敗する。
この想定外の振る舞いは、ArelのInノードが誤ってEqualityノードのサブクラスになっていたことによる。私見ではほぼバグと思われるが、この振る舞いに依存している人もいる(#39288も参照)。
残念ながらこの暗黙のcreate_withには、orがSTIサブクラスのリレーションで失敗するという不本意な副作用があった(#39956)。
今回の変更は、type_conditionを抑制したりオーバーライドする方法が変わる。#39956orの問題を修正するため、暗黙のcreate_withは、scope_for_createtype_conditionで除外される。
同PRより大意


つっつきボイス:「@kamipoさんによるArel周りの修正です」「Arel難しくて黙り込んでしまう自分😅」「説明にも書いてある#39956の問題↓を解決するためのプルリクなのでこっちを見る方がわかりやすそう」

「昔Arelのコードを叩いてゴニョゴニョするコードを見たことがあってですね」「あ〜それはつらいヤツ」「コードレビューに出すのがとてもつらくて、それ以来Arelの直いじりは止めて欲しいと思ってます」「その書き方は止めましょうと自信を持って言いたい😆」「少なくともメンテしやすいコードにはなりませんし」

参考: Rails 6.0で不要なArel.sqlを減らす - koicの日記

selenium-webdriver gemが必須でなくなった

# actionpack/lib/action_dispatch/system_testing/driver.rb#L6
      def initialize(name, **options, &capabilities)
        @name = name
        @browser = Browser.new(options[:using])
        @screen_size = options[:screen_size]
        @options = options[:options] || {}
        @capabilities = capabilities

-       @browser.preload unless name == :rack_test
+       if name == :selenium
+         require "selenium/webdriver"
+         @browser.preload
+       end
      end

つっつきボイス:「これだけ5月にマージされたプルリクなんですけど、以下の翻訳記事の原著者が投げたプルリクとのことだったので拾ってみました↓」

2020年のRailsでブラウザテストを「正しく」行う方法(翻訳)

「Selenium使わないときでもドライバが入ってきてたので必須でないようにしたと」「poltergeistとかちょっと懐かしい名前が見えた」「他のWebブラウザドライバを使うならSelenium要らないので、もっともな修正」

teampoltergeist/poltergeist - GitHub

「Seleniumに限らないけど、使わないものが入ってくると違和感ありますね」「Seleniumって依存関係もサイズも大きそうな印象ありますし」「Webブラウザのドライバだけならそこまででかくなさそうですけど、どうなんだろう?」

参考: Seleniumプロジェクトとツール :: Seleniumドキュメント

Seleniumのロゴがいつの間にかフラットなデザインに変わってますね↓(参考: 以前のロゴ)。


selenium.devより

Rails

Railsのマイグレーションはスレッドセーフであるべきか(Ruby on Rails Discussionsより)


つっつきボイス:「Railsディスカッションから拾いました」「マイグレーションは稼働中のアプリでも動作させる前提になっていることを考えるとスレッドセーフであって欲しいですけど」「そりゃその方がいいですよね😆」

「そうか、マルチプルDBだと複数のマイグレーションが同時に走る可能性もないわけじゃないのか」「schema migrations tableもDBごとにありそうですし」「この辺あんまり考えたことなかったな〜」

参考: Active Record マイグレーション - Railsガイド

「DB単位で同時にマイグレーションが走ることはないけど、DBをまたいだアプリケーション全体レベルで考えると2つのDBのマイグレーションが同時に実行されることはありそう」「そのときにスレッドセーフに書くべきかどうかということですか、やっと理解」「自分は踏んだことないんですけど、2つのデータベースが密に連携してたりするとデッドロックしたりするのかな?」「いわゆる競合状態のお手本にありそうなシチュエーションっぽい」

「この辺は推測になりますけど、Railsレベルでは複数DBを跨いだマイグレーションの同時実行制御はしてなさそうな気がします: DBをまたいで保証しようとしたら相当大変そうですし」「一般的にDBをまたいで相互にロックするようなマイグレーションはあんまりしないと思いますけど、やったらどうなるのかな?」

「マルチじゃない場合、schema migrations tableをトランザクションでロックするぐらいはしてるかも: そしたらrakeタスクが複数動いてもスレッドが同時にクリティカルセクションに入ることはなくなるのでrakeタスクを実行しても大丈夫でしょうけど」「それがマルチDBになると、複数のDBをまたぐ処理を書いたらスレッドアンセーフになる可能性はありそう」「あ、ちょっと見えてきたかも」「1つのデータベース単位ではマイグレーションがスレッドセーフでも、データベースが複数になったらクリティカルセクションを同時に通るときに何か起きそうな感じですね」


追いかけボイス: Railsレベルではマイグレーションロックがあるみたいですね。

参考: Railsのmigrationにロックが掛かっているのか調べた(Mysqlの場合) - Qiita

bundle execすべきかどうか、それが問題だ(Ruby Weeklyより)


つっつきボイス: 「記事は見出し冒頭にあるようにBundler入門という感じですね」「割と基本的な話みたいでした」「サブタイトルの方が目立ってる😆」

Railsのbinstub

「ところで今のRails wayではbundle execよりbin/railsみたいなbinstubから実行するのが正式じゃなかったっけ?」「はい、最近はRailsガイドでもそうなってるはずです」「まあ自分は今もbundle execでやっちゃいますけど😆」「実は私も😆」

参考: Rails のコマンドラインツール - Railsガイド

bin/railsって気にしたことなかったんですけど、bundle exec railsと同じということなんでしょうか?」「同等でよかったと思います」「へ〜」

「今のRails wayではbin/の下にあるbinstubもGitにコミットすることになってますし、.gitignoreでもbinstubは無視されないようになってますし」「え〜、自分まったく気づかずにずっとbundle execでやってた😭」「bundle execでも間違いではないと思います」「使っても大丈夫ですよ〜」

「あくまでRails wayとしてはbinstubが正式ということなので、Railsの教科書やリファレンスを書くならbin/railsとかで書くべきでしょうね」「なるほど、そういう本でbundle execを使いまくってたら違うと」「まあ細かい話なのでそんなに気にしすぎることはありませんけど、一応ということで」

「ところでいつ頃からRailsでbinstubが正式になったんだっけ?」「Rails 4あたり?」「そんな昔からだったんですね…」「binstubの話は当時ことさら話題になってなかったような覚えあります」

後で調べると、どうやらRails 4の頃みたいです↓。

参考: Rails 4.0 と bundler install --binstubs について - おもしろwebサービス開発日記


【翻訳+解説】binstubをしっかり理解する: RubyGems、rbenv、bundlerの挙動

RSpec Queue: RSpecをパラレルに分散実行(Ruby Weeklyより)

skroutz/rspecq - GitHub


つっつきボイス:「Rspecをキューイングしてパラレルに実行できるヤツか」「RSpec Queueのgem名がrspecqってなっているのが個人的に好き❤️」「短くてよくわかりますし」「こういうネーミングセンスを身に付けたい」

「こうやってワーカーを分けてビルドidを付けるといい感じにキューイングしてくれるみたい↓」「おぉ〜」

# 同リポジトリより
$ rspecq --build=123 --worker=foo1 spec/

「RSpecってそのままだとパラレルにならないから、こういう形でパラレルにすることになるのかな?」「完全おまかせでパラレルにするよりも多少制御はしやすいでしょうね」「すごく大きいテストだとうれしいかも」「前処理が極端に重いテストなんかも制御しやすいかも」「テストのワーカーをいっぱい立ち上げたときなんかだと、完全にラウンドロビンにするんじゃなくて多少制御したいこともありそうですし」

参考: ラウンドロビン - Wikipedia

Rubyと「Firefox Send」で巨大ファイルをセキュアに転送する

Sendは無料の暗号化ファイル転送サービスで、任意のブラウザから安全かつシンプルにファイルを共有できます。エンドツーエンド暗号化を用いて、ファイルを共有した瞬間からファイルを開くまでの間のデータをセキュアに保ちます。
同記事より


つっつきボイス:「Firefox Sendって何でしょう?」「ブラウザ内のサービスなのか外部サービスなのかと思ったら、どうやらMozillaがやってる外部サービスみたい」「ブラウザ同士の認証不要なファイル転送をサポートするインフラというかサービスっぽい」「コマンドライン版もあるのね↓」

timvisee/ffsend - GitHub

「any browserってあるからどのブラウザでもやれそう」「記事ではOpen3でRubyから操作してますね↓」「デカいファイルを渡すときに四苦八苦することがときどきあるので、こういう手段があると知ってたら使うかも」「あとはそれを思い出せるかどうか😆」

参考: module Open3 (Ruby 2.7.0 リファレンスマニュアル)


動画では期限を設定できて、最大2.5GBまで扱えるとありますね。なお、後で見たら「改装中」となっていました↓🚧。


send.firefox.comより

その他Rails


つっつきボイス:「ついさっき流れてきたツイートです」「Everyday Rails買うとこんなおまけがついてくるのね」「Rails独自のMinitest拡張ってあんまり気にしたことなかったかも」

参考: Everyday Rails… Aaron Sumner 著 et al. [Leanpub PDF/iPad/Kindle]

RailsとMinitest

「自分はRailsアプリでMinitest使おうと思ったことないな〜」「お、自分は新しいRailsプロジェクトはしれっとMinitestで書き始めましたよ😋」「私も今度はこっそりMinitestにしようと思ってます」「え〜、マジですか?😳」

参考: library minitest/unit (Ruby 2.0.0)

「RSpecってセットアップも毎回地味に面倒じゃないですか: 今やってるのは自分がrails newから始めてるので速攻でMinitestでセットアップしましたし」「やべ〜今までRSpecちまちま入れてたけど、今度は自分もMinitestでやってみようかな…😅」「作っているのはAPIサーバーなのでそんな高度なことがしたいわけでもありませんし、それならMinitestのassertでいいよねって思いますし」

RSpecえかきうた


つっつき後のツイートです。

Ruby

Ruby 3の型付け進捗


つっつきボイス:「Rubyの型付け進捗気になってた」「soutaroさんとSorbetブログで2つ記事が出てました」「RBSという型付け用DSL」「何の略だろう…?」

ruby/rbs - GitHub

RBSとはRubyプログラムの構造を記述する言語で、これを用いてクラスやモジュールの定義(クラス内で定義されたメソッド、インスタンス変数とそれらの型、継承関係やmix-in関係)を書き下せます。定数やグローバル変数も定義できます。
同リポジトリより大意

# 同リポジトリより
module ChatApp
  VERSION: String

  class User
    attr_reader login: String
    attr_reader email: String

    def initialize: (login: String, email: String) -> void
  end

  class Bot
    attr_reader name: String
    attr_reader email: String
    attr_reader owner: User

    def initialize: (name: String, owner: User) -> void
  end

  class Message
    attr_reader id: String
    attr_reader string: String
    attr_reader from: User | Bot                     # `|` means union types: `#from` can be `User` or `Bot`
    attr_reader reply_to: Message?                   # `?` means optional type: `#reply_to` can be `nil`

    def initialize: (from: User | Bot, string: String) -> void

    def reply: (from: User | Bot, string: String) -> Message
  end

  class Channel
    attr_reader name: String
    attr_reader messages: Array[Message]
    attr_reader users: Array[User]
    attr_reader bots: Array[Bot]

    def initialize: (name: String) -> void

    def each_member: () { (User | Bot) -> void } -> void  # `{` and `}` means block.
                   | () -> Enumerable[User | Bot, void]   # Method can be overloaded.
  end
end

「RBSは型定義を別ファイルにするのね」「Rubyにもいよいよ型が入ってくるのか〜」「別ファイルにするのは懐かしのC言語開発で.hファイルとかを思い出すのでそんなに違和感はないかな」「すべてに型を付けなくても必要なところにだけ型を書ければいいんじゃないかなって思いますし」「自分もそう思います」

「このソルベットって?」「ソルベ(Sorbet)はShopifyが以前から手掛けているRubyの型付けですね」「アイコンが可愛い❤️」

速報: Ruby向け型チェッカー「Sorbet」をStripeがオープンソース化


1本目記事流し読み:

  • Ruby 3のRBSという型シグネチャ用言語を発表
  • 背景:
    • 動的型付けvs静的型付けは古くから問題にされている: 静的型付けは大規模プロジェクト向きだが柔軟性が低下し、動的型付けは短期開発に向いているがコードベースの規模や人数の拡大が難しい
    • 4年前にMatzがRuby 3で静的型チェックを導入すると宣言以来、さまざまな言語の型チェックを調べたうえでRubyコミュニティは型チェッカー構築基盤の開発を決定した
  • RBSは以下のような感じ
# 同記事より
# sig/merchant.rbs

class Merchant
  attr_reader token: String
  attr_reader name: String
  attr_reader employees: Array[Employee]

  def initialize: (token: String, name: String) -> void

  def each_employee: () { (Employee) -> void } -> void
                   | () -> Enumerator[Employee, void]
end
  • RBSの主な機能とRubyの重要な特性
    • ダックタイピング
    • 不統一性(non-uniformity)
  • RubyプログラムでRBSの型を使ってできること
    • バグを見つけやすくなる
    • nil安全性
    • IDE統合の向上
    • ダックタイプをより安全に
  • SorbetとRBS
    • RubyコミュニティはSorbetチームとも連携し、RBSがSorbetやSorbet独自のRBI型シグネチャ形式とぶつからないようにしている
    • SorbetやSteep(Ruby製でRBSを使用)のような静的型チェッカーもRBSの型定義を使える
    • 相互利用のためRBS gemにはRBI->RBS変換機能も付属(逆変換は開発中)
  • まとめ

soutaro/steep - GitHub
pocke/rbs_rails - GitHub

カロリーメイトとQuine

既にあちこちでバズってますが。


つっつきボイス:「かなり盛り上がってますね」「mameさんの書いたQuine、マーケティング用のサイトにこういうのをしれっと仕込むオーバーキル感がすごい」「読める気がしない…」

# otsuka.co.jpより
caloriemateliquid .Quine $ cat CML_quine.rb
    n=2;eval$s=%q{Z=?\s;eval"$><<S=Z*4"+(%w{+"n=#{-~n%3};eval$s=%q{#$s}#YE";$>.isat ty&&
   (r="\e[43;3#{C="#{n*5%9+1}m"}#{T}\e[4"+C+S[1568,79]+E="\e[0m";r[81,21]="\e[37m# {(["Ca
  f\u00e9_au_lait","Yogurt","Fruit_mix"][n].chars*Z).tr(?_,"").center(21)}\e[3"+C ;a=%~POS
  A[`ER]`PASX1cTc22V6NNP.QOYGMXXIG7KK:bCCaVN8WZ[]UQMMS`cBFFJJHHY`QTUIUURRPTOcRV_a LLUT`WXL
 W]a_c_bV`XXYa_9}+[T='  B  A  L  A  N  C  E  D   F  O  O  D  ']*0+%w{bZZYb_][9cc ????`9^acG
 G,,N9DU`DKcUKU3K4!4!4!QXTSSS""9`9`#U`KcK--S;;/GOT<QE$U=>F==Q0@%U/P/B=S0Q`PM&XVV V15CMRHMSH
RKO>==QMQVR    'b`&DK>BS<XE$T>T33DDDUM<V@@E(((TCT0A<0A"')5CXPcQa54X@@Y#KcK--S;; /GOT<Q`$)T)T
:a4A%%#X   VS6a   '   b`&DK>BS<T7**]  ^^b6+++]~;   P=Str    uct.new(:x,:d,:p,:v );M=(-5**7..
b=0).m   ap{[]};A=s  =[];t=Time.now;q=?y.succ;(    s=S     .scan(/.+/ );M[0]<<P [25i-b%3*5i-
9,0,0  ,2+1  i] ;6  0.t   ime  s  {  |i    |j=  i  %2  0  ;i<  40 ?    [    M[j -1],m=M[j],M
[j+1  ]].  ea  ch  {|  n|  m.   ea  ch  {|  p| n. ea ch  {|  q|  d=p .x  -q  .x ;w=d.abs-4;w
<0&   &(  i<2 0?  p.  d+=  w  *w:  p.     p+=  w    *(   d  *(3 -p. d-     q.d) +(p.v-q.v)*4
)/p   .d  )}  }   }   :M  .  shif  t   .ea c  h{   |p|  y,  x=  (   p.  x+= p.v +=p.p/10).re
ct;   p.p   =  [4  3-   b/9 .0-y,1  ].    m  in- [x,p  .d=0   ,  x   -9    2].s ort[1]*2i;p.
v/=[   1,p.v.a   bs/2].max;M[20-j+[0  ,(x+  4).div(5   ),19].sort[1]]<<p;35.tim es{|w|v=x.to
_i-3+w         %7;c=s[w=y.div(2)-2+        w/7];(x-v)**2+(y-w*2)**2<16&&0<=w&&c &&(k=(w*2-21
 )**2/99)<=v&&c[v]&&k+79!=v&&c[v]=q}}};(24-b/18..21).map{|k|s[k]=Z*(k=(k*2-21)** 2/99)+q*79
 +Z+q*2*(6-k)};s*="\e[B\r";"  Your favorite flavor  ";b+=1;A<<"\e[A\r"*21+s.gsub (/\172+/){
  "\e[43m"+$&.tr(q,Z)+E})while+s.count(q)<1950;A.map{|q|sleep([t-Time.now+3,2e-2] .max);$>
  <<s=q};$><<s.gsub(?m,";33m").gsub(Z){S.slice!(/./)};b=?]*33.upto(91){|i|a=~/../ ;a=$'.gs
   ub(i.chr,$&)}*2;Z<<8;(b+a.gsub(?^,"^]"*41)+b).bytes{|c|c-=86;c<8?sleep(3e-2):$> <<(c<(
    'CalorieMate-Liquid-Quine';9)?r.slice!(/\e.*?m|./):c>9?"\e[%X"%c:Z)});puts})*"" }#YE

ちょっと整形しようとして諦めました😅。


直接関係ありませんが、mameさんご本人が別のコードで音楽付き動画をアップしているのをruby-jp Slackで知りました。なるほどの選曲です。

参考: 水上の音楽 - Wikipedia

Rubyのcoercion系メソッドには注意(Ruby Weeklyより)


つっつきボイス:「nilのcoercion(強制型変換)に注意しようという記事みたいです」「Rubyのcoercionってそんなにあったかなと思ったらto_iみたいなヤツね」

# 同記事より
nil.to_h => {}
nil.to_a => []
nil.to_f => 0.0
nil.to_r => (0/1)
nil.to_c => (0+0i)

参考: 型変換 - Wikipedia

「文字列のto_iはたしかに予想外のことになりやすい↓」「まあ使い方がよくないという説もありますけど」

# 同記事より
"312".to_i
# 312

"312 oh hai".to_i
# 312

「大文字で始まるInteger()みたいなcoercionメソッド↓、そういえばこういう機能あったな〜」

# 同記事より
Integer(nil)
# TypeError (can't convert nil into Integer)

Float(nil)
# TypeError (can't convert nil into Float))

「昔は使った覚えあるけど基本的にはcoercionってそんなに使わないかも」「Integer(nil)ってダメなんだ😳」「ホントだ、今やってみたらエラーになった」「こういうのを型チェックで救えるといいですよね」「書いた時点で見逃すとなかなか見つからなくてproductionでnilエラーになったりするヤツ」

後で気づきましたが、記事を書いた人はvirtusやdry-typeを作った方でした。

solnic/virtus - GitHub
dry-rb/dry-types - GitHub

以下の翻訳記事も趣旨が似ていますね。

Rubyの明示的/暗黙的な型変換についてのメモ(翻訳)

Rubyのrescueでやんちゃしてやった(Ruby Weeklyより)


つっつきボイス:「パーサーの目を盗んでrescueにクラス定義を書いたということみたいです」「壊しに行く気満々のコード😆」

# 同記事より
begin
  raise "omg"
rescue =>
  (class Box
   class << self
     attr_accessor :contents
   end
end; Box).contents
end

puts Box.contents

# => "omg"

「こういう凶悪なコード、よく考えつくな〜」「やったらできちゃうんですね」「Ruby公式とかに投げたら盛り上がりそう」

その他

コントのような


つっつきボイス:「200mばかし離れたところに物理サーバーを無停止で移設せよというミッションを頑張ってクリアしたそうです」「本当にそういうミッションがあったんですか?」「5分ぐらいサーバー止めたらダメ?って聞いたら一瞬たりともダメと言われてますね😆」

「移設元サーバーのインターフェイス次第ですけど、意外にやりようはありそう: 電源は今の時代ならUPSつないで発電機回せば割とどうにでもなるんですけど、それよりネットワークが切れないようにする方が大変そうかな🤔」「そんな感じですね」 「移設元と移設先で上流の同じスイッチにつなげられるならやりやすいんですけど」「DNSアップデートとか書いてるから別ネットワークなのかも」「ネットワークが変わると途端に大変になるんですよ…完全なゼロダウンタイムは難しいでしょうし」「お、記事見ると移設先から延々ネットワークケーブルを引いて、先にネットワークを移行してからカートに乗せて移動してるのか、それならやれるかも」

「それにしても一瞬たりとも止められないサーバーって…」「それならどこかクラウドのデータセンターに置けばいいのにって思っちゃいますけど」「作業料の他にコンサル料ももらったって書いてあってよかったよかった」「じゃいいか😆」

「こういうのを考えること自体は結構楽しいですよね😋」「やった人お疲れさまです!」「こういう移行方法の問題点は、途中で何かあったときのリカバリープランがないことですけど」「雨が降ったらどうするとか」「ネコがケーブルかじったりとか」「子どもがぶつかってサーバー落っことしたりとか」「周りを用心棒で固めないと」「途中に道路があったらさらに大変そう…」

「こういうの最近あんまりやってないけど、たまにやると楽しいんですよ」「責任抜きでやれるなら😆」「ISUCONの物理サーバー版みたいな企画あったら面白いかも」

参考: ISUCON公式Blog

後で日本語記事も出ましたね↓。

参考: 物理サーバーを稼働させたまま引っ越しさせた意外な方法がネットで話題に - GIGAZINE


今回は以上です。

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

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

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

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

Rails公式ニュース

Ruby on Rails Discussions

Ruby Weekly


CONTACT

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