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

週刊Railsウォッチ: Ruby 3.2のData#initializeの設計、ruby-openai gemほか(20230222後編)

こんにちは、hachi8833です。

Firefox 110がリリースされて、主要ブラウザでコンテナクエリが使えるようになりましたね。

参考: コンテナクエリ @container が全ブラウザ対応。新時代のレスポンシブ対応を完全理解する

週刊Railsウォッチについて

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

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

お知らせ: 来週は週刊Railsウォッチに代えて通常記事を公開します🙇

🔗Ruby

🔗 Ruby 3.2のData#initializeにキーワード引数も位置引数も渡せる理由


つっつきボイス:「Ruby 3.2のDataを手がけたコミッターの1人であるzverokさんのこの記事を翻訳していて、Dataで定義したものには値をキーワード引数で渡すことも位置引数で渡すこともできることを今頃知りました↓」「Ruby 3.2のDataはまさに"俺たちが欲しかったもの"だと思います」「RubyのStructがこれまで思いの外使いにくかった面はありますね」「DataはRuby 3.2で一番使いたい機能👍」

# 同記事より
Point = Data.define(:x, :y)

p1 = Point.new(1, 2)       #=> #<data Point x=1, y=2>
# or...
p2 = Point.new(x: 1, y: 2) #=> #<data Point x=1, y=2>

参考: class Data (Ruby 3.2 リファレンスマニュアル)
参考: class Struct (Ruby 3.2 リファレンスマニュアル)

「記事によると、Ruby 3.2ではStructで定義したものにも値をキーワード引数/位置引数で渡せるようになっているんですね↓」「そうそう、この間触れたkeyword_initオプションはこの変更に関連したものですね(ウォッチ20230201)」

# 同記事より
MutPoint = Struct.new(:x, :y)
MutPoint.new(1, 2)       #=> #<struct MutPoint x=1, y=2>
MutPoint.new(x: 1, y: 2) #=> #<struct MutPoint x=1, y=2>

「あとzverokさんの記事の冒頭で、以前も取り上げたRuby Changesサイトの更新情報にRuby 3.2を反映中と書かれていて、今見ると完了したようです↓」「このサイトの更新情報は詳しく記載されていていいですよね👍」「Ruby 2.0からの進化をまとめたRuby Evolutionという項目も凄い」

参考: Introduction - Ruby Changes | rubyreferences.github.io


追記(2023/03/08): その後翻訳記事を公開しました↓

Ruby 3.2のData#initializeがキーワード引数も位置引数も渡せる設計になった理由(翻訳)

🔗 YAMLドキュメント from hell


つっつきボイス:「この記事でYAML1.1以前に"ノルウェー問題"があったことを初めて知りました: 国名を2文字で表したときにnofalseに解釈される問題です↓(YAML1.2で解決)」「あ〜そういうことですか」

#. 同記事より
geoblock_regions:
  - dk
  - fi
  - is
  - no
  - se
# 同記事より
{"geoblock_regions": ["dk", "fi", "is", false, "se"]}

「別記事を見ると、YAML1.1以前ではこれらのものがtrue/falseと判定されていたらしい↓」

参考: YAML: The Norway Problem – Bram.us

# https://www.bram.us/2022/01/11/yaml-the-norway-problem/より
y|Y|yes|Yes|YES|n|N|no|No|NO
|true|True|TRUE|false|False|FALSE
|on|On|ON|off|Off|OFF

参考: Boolean Language-Independent Type for YAML™ Version 1.1
参考: YAML Ain’t Markup Language (YAML™) revision 1.2.2

「YAMLは元々、ちょっとしたデータを手軽に書けるようにするところから始まったデータフォーマットだと思うんですが、期待されるものやデータがだんだん大きくなってくるに連れてこういう問題が起こることがありますね」「なるほど」「YAMLの中でもヒアドキュメントや値のマージ機能など、環境や処理系のバージョンによって振る舞いが異なることもあったりしますね: おそらくですが最初のうちは厳密さよりも手軽さの方がメインだったのかなと想像しています」

「かといってJSONにもコメントが書けないなどのつらみがあるので、記事でもTOMLやJSON with commentsのような別のフォーマットを検討していますね」「コメント書けないJSONつらい...」

参考: TOML: Tom's Obvious Minimal Language
参考: JSON With Commas and Comments | nigeltao.github.io

「ちなみにGitLabのCI(GitLab Runner)でもTOMLが使われています」

参考: Advanced configuration | GitLab

「その記事には書かれていませんが、ここ数年JSON5というECMAScript 5.1を取り入れたフォーマットも登場しているようです↓」「JSONがあまりにも普及してるので、JSON5が流行るかどうかは既存のJSONライブラリがJSON5をどこまで処理できるようになるか次第かな」「たしかに」「JSON5が普及するためには既存のライブラリが地道に対応していくのが確実でしょうね」

参考: JSON5 – JSON for Humans | JSON5

「考えてみれば、JSONもJavaScript Object Notationの略だけあって、昔はroot要素にオブジェクトしか置けなかったりしましたね: 今はroot要素に配列も使えますが、すごく古いJSONライブラリだと使えないこともありました(さすがに最近はないと思いますが)」

🔗 Rubyの例外処理のパフォーマンス(Ruby Weeklyより)


つっつきボイス:「Rubyの例外処理をベンチマークで調べながら例外処理のパフォーマンスへの悪影響を抑える書き方を解説している記事ですね: 例外処理が遅くなるのは仕組み上仕方ないと思います」

# 同記事より
       user     system      total        real
return codes  0.044149   0.000053   0.044202 (  0.044223)
exceptions  0.508261   0.011618   0.519879 (  0.520129)
 => 
[#<Benchmark::Tms:0x000000014106b598
  @cstime=0.0,
  @cutime=0.0,
  @label="return codes",
  @real=0.04422300006262958,
  @stime=5.2999999999997494e-05,
  @total=0.04420199999999999,
  @utime=0.044148999999999994>,
 #<Benchmark::Tms:0x000000015486d8f0
  @cstime=0.0,
  @cutime=0.0,
  @label="exceptions",
  @real=0.5201290000695735,
  @stime=0.011618000000000003,
  @total=0.5198790000000001,
  @utime=0.5082610000000001>]

「記事の"Use exceptions for exceptional situations"は、例外はあくまで例外的な状況で使えということですね」「例外は文字通り通常の処理では起きないものなので通常のフローに使うのは避けたい: 例外が発生するとrescueの場所を探索しないといけなくなるし、rescueで条件が追加されるとさらに遅くなるし、通常のパイプライン処理も効かなくなるし、どうやっても遅くなる」

参考: パイプライン処理 - Wikipedia

🔗 by: Rubyライブラリのプリローダー(Ruby Weeklyより)

jeremyevans/by - GitHub


つっつきボイス:「"Polished Ruby Programming"の著者でもあるJeremy Evansさんのgemです」「プリロードしたい大きなライブラリをby-serverで起動しておいてbyで読み込めるようになるらしい↓: ライブラリの読み込みをどうしても高速化したいときなどにいいかも」

# 同リポジトリより
$ by-server sequel roda capybara

$ by -e 'p [Sequel, Roda, Capybara]'
[Sequel, Roda, Capybara]

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

🔗 ruby-openai: RubyでOpenAIを使える(Ruby Weeklyより)

alexrudall/ruby-openai - GitHub


つっつきボイス:「RubyでOpenAIを使う解説記事の中でruby-openaiが紹介されていました」「機械学習やAIだとPythonが使われることが多いですが、これはOpenAIのAPIトークンがあれば普通に使えそうな感じ」

# 同記事
require "ruby/openai"

client = OpenAI::Client.new(access_token: 'YOUR_API_TOKEN')

prompt = 'Explain metaprogramming to a 10-year-old?'

response = client.completions(
    parameters: {
      model: "text-davinci-003",
      prompt: prompt,
      max_tokens: 2000
    })

puts response['choices'][0]['text']

参考: OpenAI
参考: OpenAI - Wikipedia


つっつき後にAPIキー(personal)を取得して渡してみると、あっさり動きました↓。

irb(main):037:0> puts response['choices'][0]['text']
# 結果↓

Ruby metaprogramming is a term used to describe the act of writing code that dynamically alters other code. It involves features in Ruby such as modules, classes, and method calls. Ruby metaprogramming allows developers to write code that works with other code in a more consistent and efficient way. This can be used to reduce coding time and increase code re-usability.

参考: API Reference - OpenAI API

🔗 その他Ruby


つっつきボイス:「Ruby関連ニュースサイトのRubyFlow自身のアナウンスです」「RubyFlowのホスティングがHerokuからfly.ioに移行したのね」「たまたまかもしれないけど、先週もRails 7.1のDockerの話題でfly.ioが登場していましたね(ウォッチ20230214)」「fly.io、もしかして流行りつつある?」「今後を見ないとわからないけどfly.ioは気になっています」

参考: Deploy app servers close to your users · Fly

🔗 設計・セキュリティ

🔗 スライド『30分でわかるデータ指向アプリケーションデザイン』


つっつきボイス:「はてブで見かけて、例のApache Parquetなどにも触れていたのが気になったので取り上げてみました」

参考: Apache Parquet

「このあたりとかは、具体的な方法は違うけどユニケージを思い出す↓」「ユニケージは前職でがっつりやっていたことがありますが、そういう感じはありますね」

参考: ユニケージ開発手法 - Wikipedia

「トランザクションの話」「ACIDの中でも分離性が強調されていますね」

参考: ACID (コンピュータ科学) - Wikipedia

「そして分散トランザクションの話: リーダー選出を追求するとサービスディスカバリーも問題になってくる」

「ちなみにスライドに映っているVLDBやSIGMODはデータベース関連では世界トップレベルの国際会議で、前者はVLDB Endowment Inc.という組織が、後者はACMという国際学会が運営しています」

参考: International Conference on Very Large Data Bases - Wikipedia
参考: SIGMOD Website

「テーブルの意味づけが昔とは変化している、たしかにそうですね」

「いいスライド👍: スライド作者が監修した『データ指向アプリケーションデザイン』↓もよさそうなのでポチりました」

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

🔗 Cネイティブ拡張を使うgemが必要なAWS Ruby Lambdaを構築する(Ruby Weeklyより)


つっつきボイス:「そうそう、Lambdaでpure Rubyだけで書かれたコード(gemもRubyのみ)をリリースするなら、ソースコードをそのままzipにパッケージしてやれば動くんですが、Cネイティブ拡張を含むgemを使う場合、ランタイム側にライブラリがなければ追加してあげる必要があったり、そもそも同等の環境でコンパイルしたものをzipに入れる必要があったりで何かと面倒が増えがち」「たしかに」「AWS LambdaではできるだけRubyだけで書かれたgemを使う方が何かと楽ですね」

参考: Ruby による Lambda 関数の構築 - AWS Lambda

# 同記事より
dir=`pwd`
bundle config set --local deployment 'true'
docker run --platform=linux/amd64 \
  -e BUNDLE_SILENCE_ROOT_WARNING=1 \
  -v `pwd`:`pwd` \
  -w `pwd` \ 
  amazon/aws-sam-cli-build-image-ruby2.7 bundle install
bundle config unset deployment
bundle config unset path

「記事はDockerで解決する方法を解説していますね↑: ビルド済みのものをLambdaにデプロイする方法はAWS公式ドキュメントに記載されていたと思います」

参考: .zip ファイルアーカイブで Ruby Lambda 関数をデプロイする - AWS Lambda

🔗言語/ツール/OS/CPU

🔗 ChatGPTを賢くするコツ


つっつきボイス:「"プロの編集者"といったロールや、何を出力するかなどを明確にして質問することでChatGPTの精度を上げられる、なるほど」「ChatGPTがマークアップも認識できるってすごい」

#命令書:
あなたは、プロの編集者です。
以下の制約条件と入力文をもとに、 最高の要約を出力してください。

#制約条件:
・文字数は300文字程度。
・小学生にもわかりやすく。
・重要なキーワードを取り残さない。
・文章を簡潔に。

#入力文:
<ここに入力文章>

#出力文:

同記事より


特に目から鱗だったのは「あなたはプロの編集者です」と、ChatGPTに役割を与えるという書き出しです。このやり方を実践すると、明らかに回答の精度が上がります。
同記事より

「そういえばChatGPTにLaTeX混じりの文章を与えると、LaTeX表記のまま解釈して回答してくれるので、そのままScrapboxに貼れて便利です↓」

[$ s\lbrack x \mapsto v\rbrack(y)]は、変数[$ x]に値[$ v]を割り当てた新しい割り当て関数を表しています。これは、元の割り当て関数[$ s]から、[$ x]に対する値を[$ v]に変更したものです。特に、[$ y] が[$ x]と等しい場合は、[$ y]に対する値は[$ v]になります。それ以外の場合は、[$ y]に対する値は元の割り当て関数[$ s]と同じです。

参考: LaTeX - Wikipedia
参考: Scrapbox - チームのための新しい共有ノート


後編は以上です。

バックナンバー(2023年度第1四半期)

週刊Railsウォッチ: Ruby30周年記念イベント、ActiveRecord APIクイズほか(20230221前編)

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

Ruby Weekly

RubyFlow

160928_1638_XvIP4h


CONTACT

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