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

週刊Railsウォッチ: syntax_suggestがRuby標準ライブラリに追加、RubyのVisitorパターンほか(20220906後編)

こんにちは、hachi8833です。RubyKaigi会場限定でこんなイベントも開催されるそうです。

グルメガイドも出ていますね。

週刊Railsウォッチについて

  • 各記事冒頭には🔗でパーマリンクを置いてあります: 社内やTwitterでの議論などにどうぞ
  • 「つっつきボイス」はRailsウォッチ公開前ドラフトを(鍋のように)社内有志でつっついたときの会話の再構成です👄
  • お気づきの点がありましたら@hachi8833までメンションをいただければ確認・対応いたします🙏

TechRachoではRubyやRailsなどの最新情報記事を平日に公開しています。TechRacho記事をいち早くお読みになりたい方はTwitterにて@techrachoのフォローをお願いします。また、タグやカテゴリごとにRSSフィードを購読することもできます(例:週刊Railsウォッチタグ)

お知らせ: 来週の週刊Railsウォッチはお休みをいただきます🙇

🔗Ruby

🔗 syntax_suggestがRuby標準ライブラリに追加された(Ruby Weeklyより)

ruby/syntax_suggest - GitHub


つっつきボイス:「syntax_suggestがRubyの標準ライブラリに入った🎉」「お、これはたしかdead_endという名前でしたね(ウォッチ20210330): リポジトリを見ると"Rename DeadEnd -> SyntaxSuggest"というコミットが先月入っているのでリネームされたらしい」「dead_endという名前も割とイケてて気に入っていたんたけど、end以外もチェックするように強化されたから変えたのかも」「以前からあるruby -wcチェックより改善されたとリポジトリに書かれていますね」

# 同リポジトリより
Unmatched `end', missing keyword (`do', `def`, `if`, etc.) ?

  1  class Dog
❯ 2    defbark
❯ 4    end
  5  end
# 同リポジトリより
Unmatched `(', missing `)' ?

  1  class Dog
❯ 2    def speak(sound
❯ 4    end
  5  end

🔗 RubyのVisitorパターンをRubocopの例で学ぶ(Ruby Weeklyより)


つっつきボイス:「RuboCopのcopでVisitorパターンを学ぶ、なるほど」「Visitorパターンのトレードオフについて解説していますね」


同記事より

参考: Visitor パターン - Wikipedia

「copでRubyコードをチェックするには構文のASTが必要で、それを再帰的に追いかけるときにVisitorパターンがよく使われますね: 記事にもnokogirisyntax-treegraphql-rubyのようなパーサー的な処理を行うライブラリがVisitorパターンの参考として挙げられています」


同記事より

「Visitorパターンは言語によって書き方が違ってくるんですが、RubyのVisitorパターンはその中でもかなり独特な印象があります」「そういえばJeremy EvansさんもRubyのVisitorパターンは書き方が違うとPolished Ruby Programmingで解説していました↓」「自分が最初にVisitorパターンを学んだのは結城浩さんのデザパタ本だったんですが、これで学んだ人はRuby独特のVisitorパターンで少し戸惑うかもしれませんね」

『Polished Ruby Programming』(Jeremy Evans著)を読みました

以下はつっつき後に見つけたツイートです。

🔗 Rubyでクラスをインスタンス化すると何が行われるか(Ruby Weeklyより)


つっつきボイス:「短い記事です」「allocateって見慣れないなと思ったら、Class#allocateというメソッドがあるのか!」「そうそう、newの前にこっそり呼ばれるメソッドですね: たしかメモリの確保だけ行うんじゃなかったかな」「自分自身のインスタンスを生成して返すだけのメソッドか、なるほど」「普通にコードを書いていたら使わなそう」

# 同記事より
class Country
  def self.fresh(name, capital)
    instance = allocate                         # 1. 新しいオブジェクト用のスペースをアロケートする
    instance.custom_initializer(name, capital)  # 2. イニシャライザを呼び出す
    instance                                    # 3. Countryのインスタンスを返す
  end

  def custom_initializer(name, capital)
    @name = name
    @capital = capital
  end
end

p Country.fresh("Ghana", "Accra")
# => #<Country:0x000000010c5e23f8 @name="Ghana", @capital="Accra">

参考: Class#allocate (Ruby 3.1 リファレンスマニュアル)

🔗 Rubyの|=演算子

つっつきボイス:「||=じゃなくて|=とは?」「ビット演算子のOR |=が合わさった感じ?」「配列をappendする代わりに、2つの配列のunionを取った配列を新規作成するようですね↓」

「実用的かどうかはともかく、|=は自分的には割としっくりくる記法かも❤️」「スレッドの続きを見ると|=<<より遅いみたい...」「配列を毎回生成しているせいかな」

|=がありなら&=もできそうですね」「たしかに」

後で&=をやってみたらできました。|=と同様、object_idは新たに生成されていました。

>> a = [:turbo, :js]
#=> [:turbo, :js]
>> a.object_id
#=> 129700
>> a &= [:html, :js]
#=> [:js]
>> a.object_id
#=> 138980

  • 追記(2022-09-16): |=がStack Overflowで10年以上前に話題になっていたのを見つけました。

参考: programming languages - Ruby |= assignment operator - Stack Overflow

🔗 dry-schemaでYAMLファイルをバリデーションする(Ruby Weeklyより)


つっつきボイス:「dry-rbシリーズのdry-schemaでバリデーションを行う記事です」

dry-rb/dry-schema - GitHub

「ところでYAMLファイルってなまじ複数の書式が使えるのが微妙に気になりますよね: こういうふうにインデントしてもしなくても効く場合があったりとか↓」「あ、たしかに」

# 同記事より
domains:
    - domain: https://domain1.com/blog/author/coderhs
      rule: DomainOne
    - domain: https://Domain2.in
      rule: DomainTwo

🔗 Rubyの最適化

このサイトがメソッドエントリを無条件にクローンしていることに気づいた。これはbind_callが常にT_IMEMOをアロケーションしているということになる。このクローンはbindでは必須だが、bind_callでは必須ではない。

自分はStripeで働いていて、sorbet_runtime gemは呼び出しのバリデーションの一環としてbind_callを使っている。

このパッチは、convert_umethod_to_method_componentscloneパラメータを追加する。これによってクローンするかどうかを制御できるようになる。このパッチはStripe CIに渡されて私たちのQA環境では動作している。私はこのパッチを@tenderloveとともにレビューし、パッチの正しさについても議論した。
同PRより


つっつきボイス:「Stripeの人がRubyを最適化したのがマージされたそうです」「Rubyのコアにこういう最適化が入ると速くなりそう👍」

# proc.c#L2546
-convert_umethod_to_method_components(const struct METHOD *data, VALUE recv, VALUE *methclass_out, VALUE *klass_out, VALUE *iclass_out, const rb_method_entry_t **me_out)
+convert_umethod_to_method_components(const struct METHOD *data, VALUE recv, VALUE *methclass_out, VALUE *klass_out, VALUE *iclass_out, const rb_method_entry_t **me_out, const bool clone)

🔗 Rubyのerror_highlight


つっつきボイス:「@mametterさんのRubyKaigi予告記事です」「たしかにこの部分は難しそう↓: RubyKaigiの予習にどうぞ👍」

何がむずかしかったか
一言で言えば、「エラーメッセージの変更は非互換である」ということでした。
同記事より

🔗 その他Ruby


つっつきボイス:「8/15から合計ダウンロード数の多いgemのオーナーは多要素認証の設定が必須になったそうです」「これは以前rubygems.orgがgem作者に呼びかけた多要素認証設定の続報ですね(ウォッチ20220621)」

🔗DB

🔗 trilogy: GitHubによるMySQLクライアントライブラリ

github/trilogy - GitHub


つっつきボイス:「BPS社内Slackに書かれていたのを拾いました」「trilogyはGitHubが作って実際にproductionで利用しているのが強いですね」「お〜」「READMEにはプリペアドステートメント(ウォッチ20220222)はサポートしていないと書かれているのがネックといえばネックかもしれませんが、それが気にならない人は使ってみてもよさそう」

参考: プリペアドステートメントとは - 意味をわかりやすく - IT用語辞典 e-Words

🔗 設計

🔗 イベントをモデリングする(RubyFlowより)


つっつきボイス:「Event Modelingは用語かと思ったら文字通りイベントをモデリングすることを指しているようです」「UMLとだいぶ違う感じの図かも」「とりあえず時間軸は左から右に流れていますね↓」


同記事より

参考: 統一モデリング言語(UML) - Wikipedia

「図を見た感じでは、青がコマンド、オレンジがイベント、緑がビューになっていて、コマンドを発行するとイベントが発火してビューに表示されるというような処理が左から右に進む: イベントはInventory、Auth、Payment、GPSに分かれている」「なるほど」「この解説ではホテルの予約システムのような設計を念頭に置いているようですね: そういうシステムでは空き部屋状況の確認も必要になるので複雑になりやすい」


同記事より(編集部で拡大)

「全般にBDDのテストコードを思わせるところがありますね: 以下のようにGiveとWhenとThenで表すのはなつかしのcucumberでも使われていました↓」「なるほどBDDですか」「シナリオテストについても言及しているし、記事の最後でもBDDの話が出ていますね」

The specification for this has the form of “Given: A view of the tasks to do, When This command is launched for each item, Then These events are expected back.”
同記事より

参考: ビヘイビア駆動開発(BDD) - Wikipedia

cucumber/cucumber-ruby - GitHub

# cucumber/cucumber-rubyより
# features/rule.feature

Feature: Rule Sample

  Rule: This is a rule

    Example: A passing example
      Given this will pass
      When I do an action
      Then some results should be there

    Example: A failing example
      Given this will fail
      When I do an action
      Then some results should be there

「眺めてみた限りでは、この記事の方法でモデリングすることで、複雑に見えるシステムでも最終的に各部分のシナリオをBDDのfeatureとして書けるようになり、シナリオをそのままテストに落とし込んでCIで回したりできるのでいいよ、というBDD的な話のように思えました」「なるほど」

「BDD的なアプローチは以前広く流行したんですが、経験では日本語との相性がどうしてもよくないんですよ: 英語なら無理なく書けるものでも、日本語だと機械翻訳みたいな不自然な表現になりがち」

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

🔗 RFC 9293


つっつきボイス:「これもBPS社内Slackに貼っていただいたエントリです」「そうそう、従来のTCPプロトコル関連のRFCをobsoleteにしたり更新したりしてRFC 9293にまとめたものが出ましたね」

  • Status:Internet Standard
  • Obsoletes:793, 879, 2873, 6093, 6429, 6528, 6691
  • Updates:1011, 1122, 5961
    RFC 9293より

「これでだいぶ読みやすくなったんでしょうね」「従来のRFCはキメラみたいになっていて最新情報を追うのが大変だったので、最近新しく出たHTTP 1.1のRFC 9112もそうですが、こうやって整理されるのはありがたい👍」

参考: RFC 9112: HTTP/1.1
参考: RFC 9112 - HTTP/1.1 (RFC 9112) 日本語訳

🔗 AWSによるSlack経由の有償サポート


つっつきボイス:「これもBPS社内Slackからです」「AWSのサポートがSlack経由のやりとりを公式にサポートしたというニュースですね: 記事にもあるようにサポートプランが有償のBusiness、Enterprise On-ramp、Enterpriseなら追加費用なしですが、BasicやDeveloperプランは有償サポートにアップグレードしないと使えません」「残念」

「考えてみればAWSサポートのチケットトラッカー画面は自分も普段ほとんど見に行かないので、Slackでやりとりできればサポートの依頼者がサポートからの返信を見落としにくくなるでしょうね」「そうですね」

「逆にAWSサポートの立場で考えれば、Slack化することでチケットがクローズされないまま放置されるのを減らせるはずなので、むしろそっちの方がメインの目的かもしれませんよね」「たしかにサポート側はチケットをできるだけクローズして欲しいはずですよね」「チケットのクローズ率やクローズまでの期間のような値は顧客満足度の測定でもよく使われるので、そういう値を改善するためにSlack対応を始めたんじゃないかなと想像しています」

🔗言語/ツール/OS/CPU

🔗 『Midjourney、Stable Diffusion、mimicなどの画像自動生成AIと著作権』

つっつきボイス:「Stable Diffusion流行り続けてますね」「こちらの記事がはてブで大バズリしていて、自分が見に行ったときはサーバーがときどきアクセスできなくなっていました」「これは図も含めてとてもいい記事👍」


同記事より

「記事を読んでみてわかったのは、原則論はいろいろあるものの、個別のケースでは実際に裁判になってみないとはっきりしない点がいくつもあるということですね」「なるほど」「例のmimicの件も、それだけで直ちに法的責任を問われるものではないだろうという見解でしたね」

参考: AIイラスト生成「mimic」、β版の全機能を停止 不正利用などの課題を改善次第、正式版をリリース - ITmedia NEWS

🔗 NIIでメルカリのデータセットが無償公開

つっつきボイス:「国立情報学研究所(NII)でメルカリの巨大データセットが無償公開されたそうです」「お〜これはすごい」「もちろん個人情報や非公開情報は除外済みです」

「こういうデータが公開されると学部生あたりが一気に使いそう」「でしょうね」「学生はお金がないうえに、こういうデータセットには共同研究のような形でないとなかなかアクセスできませんし、かといって既に公開されているデータセットだと既存の研究でさんざん使われていて新しい研究がしにくいんですよ」「なるほど」


後編は以上です。RubyKaigiでお会いしましょう。

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

週刊Railsウォッチ: Herokuが無料プラン廃止を発表、Hotwire日本語コミュニティほか(20220905前編)

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

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

Ruby Weekly

RubyFlow

160928_1638_XvIP4h


CONTACT

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