週刊Railsウォッチ(20190617-1/2前編)マルチプルデータベースガイドが追加、mmcと「Ruby 3の型解析に向けた計画」、Ruby 2.6のCSVライブラリはいいほか

こんにちは、hachi8833です。Macbook Pro late 2013の次をどうするか心が揺れてます。


つっつきボイス:「WSL2の出来はかなり気になるヤツですね(今Windowsだし❤️)」「結局POSIX APIを頑張ってラップしてどうにかするのを諦めてLinuxカーネルを内包する流れになったという😆」「WindowsのPOSIX APIはつくづく👎だったけど、あれはまあ別物ですし」「今macOSのbashとParallels DesktopのUbuntu VMのbashの二重生活なんですけど😢、WSL2でもさすがに1つにはならないんでしょうか?」「ハイパーバイザでLinuxを動かすならまあDocker for Windowsを使ってるのと大差ないですね😆」「やっぱり〜😆」

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

お知らせ: 第12回公開つっつき会(無料)

開始以来ついに1年目を迎えた第12回目公開つっつき会は7月4日(木)19:30〜にBPS会議スペースにて開催されます。皆さまのお気軽なご参加をお待ちしております🙇。

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

今回はコミットリストから見繕いました。ドキュメント更新がだいぶ増えています。


つっつきボイス:「そろそろRC2が出そうかなと」「これだけかかるとRC2必要でしょうね😆」

MessageEncryptoron_rotationがコンストラクタで渡されるようにした

  • メッセージの暗号解除/検証時に使われるon_rotation procをコンストラクタのレベルで渡されるようにした
    Before:

    crypt = ActiveSupport::MessageEncryptor.new('long_secret')
    crypt.decrypt_and_verify(encrypted_message, on_rotation: proc { ... })
    crypt.decrypt_and_verify(another_encrypted_message, on_rotation: proc { ... })

    After:

    crypt = ActiveSupport::MessageEncryptor.new('long_secret', on_rotation: proc { ... })
    crypt.decrypt_and_verify(encrypted_message)
    crypt.decrypt_and_verify(another_encrypted_message)

つっつきボイス:「暗号化で言うローテーションでしょうか?」「on_rotationはどうやら鍵のフォールバックで使うものらしい」

MessageEncryptorは、encryptorのスタックへのフォールバックによって古い設定のローテーションをサポートする。rotateを呼んでビルドし、encryptorを追加すると、decrypt_and_verifyでもフォールバックを試行する。
ローテーションされたencryptorは、デフォルトでは他を指定されてない場合プライマリのencryptorを用いる。
api.rubyonrail.orgより大意

「ちなみに、鍵を変えないといけなくなる状況ってやっぱりあって、極端な場合は、間違えてsecretをコミットしちゃったとかお漏らししちゃったとか😅」「あ〜」「そこまでいかなくてもsecretを知っている人が退職したときなんかもそうですね: 正直面倒ですし、NDAで縛るという手もありますが、やはり鍵はちゃんと変えるべき」「ですね😅」

on_rotationは新しいらしく、6.0↓には入ってますがRails 5.xのAPIにはありませんでした。

Action Viewのテストをパラレル実行

# actionview/test/abstract_unit.rb#L194
class ActiveSupport::TestCase
+ parallelize
+
  include ActiveSupport::Testing::MethodCallAssertions

  private
    # Skips the current run on Rubinius using Minitest::Assertions#skip
    def rubinius_skip(message = "")
      skip message if RUBY_ENGINE == "rbx"
    end
    # Skips the current run on JRuby using Minitest::Assertions#skip
    def jruby_skip(message = "")
      skip message if defined?(JRUBY_VERSION)
    end
end

つっつきボイス:「parallelizeって書くとパラレルになってくれるんだ!」「せっかく作ったのに書き漏れてたから足したっぽい」「パラレライズって何となく麻酔が効きそうな響き(それはparalyze)😆」

      def parallelize(workers: :number_of_processors, with: :processes)
        workers = Concurrent.physical_processor_count if workers == :number_of_processors
        workers = ENV["PARALLEL_WORKERS"].to_i if ENV["PARALLEL_WORKERS"]

        return if workers <= 1

        executor = case with
                   when :processes
                     Testing::Parallelization.new(workers)
                   when :threads
                     Minitest::Parallel::Executor.new(workers)
                   else
                     raise ArgumentError, "#{with} is not a supported parallelization executor."
        end

        self.lock_threads = false if defined?(self.lock_threads) && with == :threads

        Minitest.parallel_executor = executor

        parallelize_me!
      end

parallelize_me!ですって。

値をnumericで返すアダプタに統一

# activerecord/test/cases/calculations_test.rb#L591
  def test_should_sum_expression
-   if current_adapter?(:SQLite3Adapter, :Mysql2Adapter, :PostgreSQLAdapter, :OracleAdapter)
-     assert_equal 636, Account.sum("2 * credit_limit")
-   else
-     assert_equal 636, Account.sum("2 * credit_limit").to_i
-   end
+   assert_equal 636, Account.sum("2 * credit_limit")
  end

つっつきボイス:「前は一部のアダプタのテストでto_iしてたのが要らなくなった?」「SQLite3とMySQL2とPostgreSQLとOracleは前からnumeric値を返してたのね」「こんな違いがあったなんて知らんかった〜」「この4つ以外にRailsがサポートしているアダプタって何があるんだろか😆」「わかりません😆」「よくぞ見つけたという感じ」

「numericでなかった場合は何が返ってきたんでしょう?」「文字列ではないかと☺️」「あ〜」「BigIntかな?と思ったけどそれなら問題ないはずだし」

safe SQL文字列関連


つっつきボイス:「@kamipoさんがsafe SQL関連のコミットをいくつか投げてたので」「え、そもそもNULLS FIRSTと書ける↓なんて知らなかった!😳」「ぽすぐれとOracleの構文なのか」

# activerecord/test/cases/relations_test.rb#L338
  def test_reverse_order_with_nulls_first_or_last
    assert_raises(ActiveRecord::IrreversibleOrderError) do
-     Topic.order(Arel.sql("title NULLS FIRST")).reverse_order
+     Topic.order("title NULLS FIRST").reverse_order
    end
    assert_raises(ActiveRecord::IrreversibleOrderError) do
-     Topic.order(Arel.sql("title  NULLS  FIRST")).reverse_order
+     Topic.order("title  NULLS  FIRST").reverse_order
    end
    assert_raises(ActiveRecord::IrreversibleOrderError) do
-     Topic.order(Arel.sql("title nulls last")).reverse_order
+     Topic.order("title nulls last").reverse_order
    end
    assert_raises(ActiveRecord::IrreversibleOrderError) do
-     Topic.order(Arel.sql("title NULLS FIRST, author_name")).reverse_order
+     Topic.order("title NULLS FIRST, author_name").reverse_order
    end
    assert_raises(ActiveRecord::IrreversibleOrderError) do
-     Topic.order(Arel.sql("author_name, title nulls last")).reverse_order
+     Topic.order("author_name, title nulls last").reverse_order
    end
- end
+ end if current_adapter?(:PostgreSQLAdapter, :OracleAdapter)

NULLS FIRSTってわかる: ORDER BYしたときにnullが最初に来るか末尾に来るかが問題になることあるし」「あ〜そういうことですか!」「知らなかったわこれ〜: たしかにこれ制御したいことってあるし😋」「もちろんnullはnullなので本来的にはどうかというのはあるんですけど😆、nullを含む表示を制御したいときはあるので」「改修よりそっちの方がすげ〜感😋」

「改修は、Arel.sql使わなくてもTopic.order("title NULLS FIRST")と書けばSQLになってくれるぞと」「サニタイズしなくてもよくなったということでしょうか?」「詳しくは知らないけど、前はArel.sqlなしで書くとwarningとか出てたのが、SQLインジェクション対策が強化されたりしたことでArel.sql使わなくてもチェックされるようになったんじゃないかなと想像してます☺️」

「他の2つもsafe SQL関連みたいです」「使っていいリストに追加したんですね: お〜AS、これは書きたいヤツ😍」

# activerecord/lib/active_record/connection_adapters/abstract/quoting.rb#L162
      COLUMN_NAME = /
        \A
        (
          (?:\w+\.)?\w+
+         (?:(?:\s+AS)?\s+\w+)?
        )
        (?:\s*,\s*\g<1>)*
        \z
      /ix

「カラム名に関数を含む場合↓、これも使っていいリストに追加したと」「こういうのを汎用的に書くのって大変ですよね😭」

# activerecord/lib/active_record/connection_adapters/abstract/quoting.rb#L158
      COLUMN_NAME = /
        \A
        (
-         (?:\w+\.)?\w+
+         (?:
+           # table_name.column_name | function(one or no argument)
+           ((?:\w+\.)?\w+) | \w+\((?:|\g<2>)\)
+         )
          (?:(?:\s+AS)?\s+\w+)?
        )
        (?:\s*,\s*\g<1>)*
        \z
      /ix

「こうやっていろいろよくなってくるとRails 6.0に期待しちゃいますね😋」

番外: privateの次の空白行を削除

# ctioncable/lib/action_cable/server/worker.rb#L68
      private
-
        def logger
          ActionCable.server.logger
        end
    end

つっつきボイス:「修正はちょろいんですが、更新ファイル数がめちゃ多かったので😆」「RuboCopのLayout/EmptyLinesAroundAccessModifierが追加されたと」「アクセス指定子(private)の前は空行あり、次は空行なしがRuboCopのデフォルトだったかな」

「このprivateから先のインデントを1つ下げるかどうかという議論もありますよね😆」「privateの先はインデントしてない(privateと同じインデントにする)の方が普通に見かける気がするんだけど?🤔」「私もそんな気がします」「インデントするのもたまに見かけますけど☺️」

privateの下はインデントする派?」「ぼくはしませんね〜☺️」「やっぱそうですよね😆」「自分もしたくない派😆」「上の変更は前からインデントしてるけど、そういう文化なのかな?☺️」

Rails

Rails 6アップグレードガイドの「オートローダー」


つっつきボイス:「この間Rails 6アップグレードガイドを更新翻訳したんですけど、やはりメジャーアップグレードだけに注意書きが普段より多めだなと思ったので」「メジャーアップグレードならありそう☺️」

「特にオートローダーがZeitwerkに変わったあたりの記述が、どちらかというと従来のオートローダー周りの謎の挙動がいろいろわかってきたという感じでした😆」「オートローダーって何か困ったことがあるまで調べませんし🤣」「6.0ではclassicモードも使えると」

Rails 6ガイドの「マルチプルデータベース」


最後に、データベースをまたがるJOINは利用できません。Rails 6.1ではhas_manyリレーションシップの利用と、JOINではなく「2つのクエリ作成」をサポートする予定ですが、Rails 6.0ではJOINを手動で2つのSELECTに分ける必要があります。
同PRより

つっつきボイス:「こちらもRails 6で追加されたマルチプルデータベースガイドなんですけど、Rails 6はデータベースをまたがるJOINをサポートしないんだそうです↑」「前回話しましたけど(ウォッチ20190610)、MySQLやPostgreSQLではデータベースをまたがるJOINはサポートされています: ここで言っているのはRailsのArelではデータベースをまたがるJOINはサポートしないということでしょうね」「なるほど!」「たしかデータベースをまたがるJOINってSQL標準から少し外れてたと思いますし、サーバー側の設定にもよると思うのでサポートしないんじゃないかなと想像してます🤔」

「まあクエリを2つ書けばやれますけどっ😆」「ガイドにもありますね」「どうしても欲しければ生SQL書けばいいんだし☺️」

なお、つっつきの後で更新情報出ました。

light-service: Service Object gem


同リポジトリより


つっつきボイス:「また別のService Object gemですけど、他のと違うところはどこかなと思って」「記事を見ると、こういう感じで一連のService Objectたちを1個のService Objectにまとめてオーガナイズする、ライトサービスオーガナイザーというもののようだ」「あ、Serviceをまとめるヤツですか」「callするとwithのところに書かれたService Objectを順番に呼んでくれるんでしょうね: reduce使ってるのはちょいどうかと思いますけど😆」

# 同記事より
class CreateOrder
  extend LightService::Organizer

  def self.call(user, subtotal)
    with(user: user, subtotal: subtotal).reduce(
        VerifyActiveUser,
        CalculateTotal,
        CreateOrderRecord,
        PayForOrder,
        SendConfirmationEmail,
        AddHistoryItemToUserHistory,
        NotifyServiceTeamOfSpecialtyOrder
      )
  end
end

「これは欲しいときありますね😍」「ちゃんと読まないとわかりませんが、この感じからして途中で失敗したときの復帰なんかもうまくやってくれそう😋」「お〜!」「gemなしで自分で書けるんでしょうか?」「まあ自分で書いてもいいんですけど、エラー処理のこととかを考えると共通ライブラリになっている方が使いやすそうではありますね☺️」

「README長い〜😅」「お、かわいい図が🐥」「オーガナイザがアクションの呼び出しをまとめているということでしょうね」「promisesってあるけど、非同期実行かと思ったらコンテキストのキーを設定するものみたい😅」


同リポジトリより

「ちゃんと動くなら悪くなさそう😋」「試してみようかな🥰」

その他Rails


つっつきボイス:「へぇ〜、ary.any?って特化命令ないのか」「特化命令って何でしたっけ?😅」「Active Recordにそういうのがあるのかなと思ったらこれのことのようですね↓」

参考: YARV Maniacs 【第 9 回】 特化命令

Ruby では今までこれをそのままメソッド呼び出しとして実行しており、これが「Ruby は遅い」と言われる原因になってきました。とくに、よく評価に利用されるマイクロベンチマーク (つまり、すごーく単純な性能評価のためのプログラム) では、この「1 + 2」のような単純な計算のコストが実行時間全体に対して多くの比率を占めるので、ここが遅い Ruby は不利になっていました。これに対して、例えば JavaVM では 1 などの整数値を特別扱いすることで性能の向上をはかっています。
そこで YARV では「1 + 2」のような単純な計算を高速に実行する工夫をしています。それが特化命令です。
magazine.rubyist.netより

Ruby

mmc: もうひとつのType Profiler


つっつきボイス:「スライドは冒頭から『タイトルは釣りです』🤣」「なるほど、Typer Profilerね☺️」「mmcってメモリマネジメントコントローラかと思た🤣」「遠藤さんがやってるのと似てる?」

「そうそう、この抽象実行↓: こういうふうにFixnumみたいな型だけを追いかける」「たぶんこのあたりはRubyKaigiの遠藤さんのスライドで追えばわかりそう☺️」「mmcはそれといろいろ関連してそうですね🤔」「いろいろおもしろいスライド😋」

「遠藤さん、RubyKaigiのときはまだまだ動かないものがあるとは言ってたけど😆」「やっぱハッシュテーブルの中も追いかけないといけないか〜」

後日


regional-gh.rubykaigi.orgより

つっつき後にmametterこと遠藤さんのとても新しいスライドを見つけました。この間の名古屋Ruby会議で発表されたそうです。

同スライドに以下の記述があることから、mmcがRuby 3の型解析に影響を与えつつあるということのようです。

もろもろ後で読んでみます😅。

Ruby 2.6のCSV最適化がスゴい


つっつきボイス:「こちらもRubyKaigi 2019の後追いですが、今日は忙しくて出られないkazzさんが『Ruby 2.6のCSVリファクタリングの話がとてもよかった: 最適化してめちゃ速くなったのにとてもきれいなコードで、最適化=汚くなるという通念を覆された』と激賞してたので集めてみました」「なるほどっ☺️」「fastestCSVってどういう位置づけなんでしょう?🤔」「おそらくRubyに元からあったCSVモジュールが遅かったので、fasterCSVというgemがあって、それがその後RubyのCSVに取り込まれたときにfastestと銘打ったんでしょうね☺️」「fastestの次はどういう名前にするんでしょう😆」

参考: FasterCSV - Ruby

「RubyのCSVは以前から結構よくできてて、文字コード変換なんかもよしなにやってくれたりするんですよ❤️」「クォートがある場合とかない場合とかでかなり細かく場合分けしてるんですね」

「出たな!KEN_ALL.csv🤣」「こういうベンチマークにはむしろうってつけですね☺️」「KEN_ALL.csv、数百MBぐらいあるかと思ったら12MBぐらいでしたか😳」「KEN_ALL.csvってたしか2種類ぐらいあった気が」「しかもcp932混じってるし😇」「KEN_ALL.csvじゃしょうがない😆」

参考: 郵便番号データダウンロード - 日本郵便
参考: KEN_ALL.CSV (郵便番号検索)の落とし穴 - Qiita
参考: 本当は怖くないCP932 - Qiita

StringScanner使うよねやっぱ😆」「ここにいる人はあまり使わないかな?」「以前もちょっと話した気はするんですが、StringScannerを使うと任意長の文字列に対してカーソル的にスキャンできる: 1文字ずつ読んだり、4文字進めたり」「へぇ〜!」「頑張れば改行を含んでたりしても処理できます: かなり地獄感ありますけど👹」「StringScannerは結構好き❤️: デバッグは大変だけど😆」

参考: class StringScanner (Ruby 2.6.0)

# docs.ruby-lang.orgより
require 'strscan'

s = StringScanner.new('This is an example string')
s.eos?            #=> false

p s.scan(/\w+/)   #=> "This"
p s.scan(/\w+/)   #=> nil
p s.scan(/\s+/)   #=> " "
p s.scan(/\s+/)   #=> nil
p s.scan(/\w+/)   #=> "is"
s.eos?            #=> false

p s.scan(/\s+/)   #=> " "
p s.scan(/\w+/)   #=> "an"
p s.scan(/\s+/)   #=> " "
p s.scan(/\w+/)   #=> "example"
p s.scan(/\s+/)   #=> " "
p s.scan(/\w+/)   #=> "string"
s.eos?            #=> true

p s.scan(/\s+/)   #=> nil
p s.scan(/\w+/)   #=> nil

CSVあれこれ

「CSVといえば、AAAA,AAAA,AAAAみたいにダブルクォートなしのもあれば"AAAA","AAAA","AAAA"みたいにダブルクォートありのもありますし、あとダブルクォートをどうやってダブルクォートの中に入れるかなんて話もあったり、もうキリがない😇」「たしかExcelのCSVは、ダブルクォートの中に出てくるダブルクォートは2つ重ねないといけないんですよね🤣」「Excelローカルルール🤣」「私そのあたりはもう理解放棄しました😇」

「そういえばCSVのRFCってあるんでしたっけ?」(ググる)「あぁ!一応あるし!」「RFC4180ですか」「2005年だけに番号若いし👶」「つまり2005年まではCSVの仕様なかった🤣」

参考: CSVファイルの一般的書式 (RFC4180 日本語訳) - アルプス登山の玄関口・笠井家

ファイル末尾のレコードの終端には、改行はあってもなくてもよい。

「改行はあってもなくてもよいなんて書いてますし😆」「あってもなくても動かないといけないとは😭」「ひど〜い😢」「ヘッダ行が存在してもよい、とかも😆」「やめて〜😅」「もう現状追認まくり😇」「こんなものでもどこかにまとまってないとつらいばっかりですよね☺️」「さっきのダブルクォートも仕様に入ってるし↓」

フィールドがダブルクォーテーションで囲まれている場合、フィールドの値に含まれるダブルクォーテーションは、その直前にひとつダブルクォーテーションを付加して、エスケープしなければならない。

「この仕様、一応ABNFになるんだ?!」「ABNFで表現できるなら一応マシか🤣」「お気持ちではなくなったと🤣」

「つまり『CSVを扱って欲しい』とか言われたら『それはRFC4180に則ったCSVということでいいんですよね?』という確認ができるのでとっても話が早くなる❤️」「それ重要!!」「CSVの仕様を個別に確認するとかしたくないですし😇」「区分がInformationalなので標準とまではいかないにしても🤣」「それでもあるだけうれしい😂」「そもそもCSV使いたくないけどっ🤣」

参考: ABNF - Wikipedia


「一説によると、CSVは『comma separated values』ではなくてタブ文字も含めて『character separated values』じゃないかって😆」「どっちだ😆」「軽くググった感じではcommaの方が多いみたいですね」「タブ区切り好きなのでcharacterを推したいです😍」

参考: Comma-Separated Values - Wikipedia

スペーシングが奇妙

# kaminari-core/test/helpers/action_view_extension_test.rb#L546
      test 'the last page' do
        users = User.page(3).per(1)
-       assert_equal'/users?page=2', view.path_to_prev_page(users, params: {controller: 'users', action: 'index'})
+       assert_equal '/users?page=2', view.path_to_prev_page(users, params: {controller: 'users', action: 'index'})
      end

つっつきボイス:「kaminari gemなんですけど、コミットのタイトルが個人的に刺さったので♫」「↑おおこれ😆: よく見つけたし」「RufoとかPrettierとかで退治したいヤツ」

「Space OddityはDavid Bowieの大昔のヒット曲で、実は一昨年のRubyKaigi@広島のRubyカラオケでこれ歌いました(外人部屋で)🎤」「ちょ😆」

参考: スペイス・オディティ (曲) - Wikipedia

Rubyのスネークケース

つっつきボイス:「こういうMatzが直に回答してくれるQ&Aが読めるってさりげにうれしいです😋」「キャメルケースをうるさいと感じる人ってたまにいますよね」「そうかも」「スネークケースは文字数が増えるからヤダという人もいたりとか」

BASIC言語よもやま

「そういえばむかーしのBASIC言語なんかだと変数名が長すぎるとメモリ食うからダメ、なんてのがありましたね😆」「私の頃のBASICはもっと古くて、変数名は何文字であっても最初の1文字しか認識されなかったので、変数は最大で26個しか使えない仕様でした🤣」「それ知らない🤣」「インタプリタってそういう縛りありがちですね🤣」「なので逆に2文字目以降は好きに名前つけられちゃいました🤣」

参考: BASIC - Wikipedia

「ちなみにこちらの若い方はBASICとかやったことって?」「1ミリもありません」「やっぱり🤣」「🤣」「じゃ触ったことのある言語で古くからありそうなのは?」「うーん、C言語っすかね😅」「あ、そりゃそうか😆」

C言語よもやま

「じゃC言語は頑張ればunion(共用体)とかあっても読めたりします?」「たぶん無理じゃないかと😆」「unionは自分もほぼ読まないし😆」「unionはLinuxカーネルとかネットワークのプロトコルスタックとかだとめっちゃ出てきますけどっ😆」「union、自分ではまず書かなさそう😅」「アラインメント合わせるときぐらいでしょうし」

参考: 共用体(union) - Wikipedia

「そういえばLinuxカーネルあたりはC言語のマクロがやたらめったら使われてますよね😆」「C言語本来の部分がめちゃ少なかったり😆」「マクロがもはや謎の拡張言語と化してる感😆」「Linuxカーネルのソース、一度読んでみるとわかりますけど、なんでこんなことがC言語でできるんだ??って思うことだらけですよもう🤣」「そんなに😆」

参考: C言語のマクロの基本

「いやもうめっちゃありますって: スレッドの構造体から、その親のスレッドが所属するプロセスを取りに行くのをマクロでやってたりしますし🤣」「なぜマクロで🤣」「スレッドの構造体はその親のスレッド構造体へのポインタとか持ってないのに、どうやってやってるんだと思って調べたらマクロでしたよ!マクロ!😇」

「それってマクロの中で処理しちゃうんでしょうか?」「そこがまたよくできていて、構造体のアラインメントが決まってるから、そこからマイナス何バイトとかやると取れる🤣」「だっはっは🤣」「C++だとコンパイラによって結果変わるかもしれないけど似たようなことやったりしますよね: ここから何バイト遡れば親の構造体があるはずみたいな」

「あんましやっちゃいけなさそうですけど😆」「何だかバッファオーバーランと紙一重😆」「Cで書かれたカーネルだとそういうのが普通に出てきますし😆、そもそもOSのカーネルだからユーザーランドと違ってバッファオーバーランではないし」「あそれもそうか😅」「OSの特権🤴」

参考: バッファオーバーラン - Wikipedia

その他Ruby


つっつきボイス:「プロのRubyプログラマーは30万人で、Rubyを使ってるプログラマーは100万人ですって」「Rubyプログラマーの数といっても、Rubyが書ける人をどう数えているのかですよね😆」


「k0kubunさんがBuildersconに応募してるのか」「まだ審査中のようですね」「Buildersconは毎年やってますね〜❤️」「何だかとっても強そう」

参考: builderscon - 知らなかった、を聞く


builderscon.ioより

2019年度は8/29〜8/31に開催だそうです。

審査中のセッション一覧を見たら、ものすごいエントリ数…!行ってみたいです。

参考: セッション一覧 - builderscon tokyo 2019


つっつきボイス:「そうそう、@kamipoさんのこのツイートなるほどというかとてもわかりみ深い😋: ぴよコードに文句を言う前に歴史を調べようぜと」「ですね〜」「コードが変だったからプルリク投げるとかではなくて、こういう歴史上の理由があって変になっていたからこう直すのが設計的にも合っているはず、までやると」「実際こういうことって結構ありますね☺️」


前編は以上です。

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

週刊Railsウォッチ(20190611-2/2後編)Dockerfileベストプラクティス、DBの冗長化、jQueryとの付き合い方ほか

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

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

Rails公式ニュース

デザインも頼めるシステム開発会社をお探しなら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の書いた記事

夏のTechRachoフェア2019

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ