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

週刊Railsウォッチ: Rubyでシリアルポートにアクセス、Active Record vs Sequelほか(20240313後編)

こんにちは、hachi8833です。


つっつきボイス:「Macを使わなくなるわけではなくてメインマシンをWindowsにするということみたい」「ところでDHHって最近までエディタにTextMate使っていたのね: 遠い昔にDHHが初めてRailsをお披露目したときの有名な動画↓でTextMateを使っていたこともあって、Macユーザーで使ってた人も割といた印象があるかな」「あの"15分でWebアプリを作る"動画ですね」

「自分が以前Sublime Textを使ってたときにTextMateを見かけたことはあったんですが、ついに使わないままVS Codeに乗り換えました」「TextMateは昔使ったことあったけど、日本語を入力するにはTextMate用のフォントを作ったりといろいろ手間かけないといけなかったんですよ」「TextMateってWindows版なかったのか...」

参考: TextMate: Text editor for macOS
参考: Macの定番テキストエディタ「TextMate」を入れてみたよ&日本語入力できるようにしたよ - bojovs blog

週刊Railsウォッチについて

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

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

お知らせ: 来週の週刊Railsウォッチはお休みをいただき、通常記事を公開いたします🙇

🔗Rails

🔗 JSの昔の書き方をTurboで使いたい(Ruby on Rails Discussionsより)


つっつきボイス:「自分の管理下にない外部のJavaScriptコード(ここではgtag)を、書き方を変えずにTurboでやる方法がないかどうかを尋ねている書き込みを見つけました」「たぶんページ読み込みの時点で存在しているElementに対して最初に1回だけ一括でaddEventListener()するような実装がいけないんじゃないかな」「Discussionの回答を見てもそのままでは無理っぽいですね」「extreme challengeとあるぐらいなのでめちゃくちゃ難しいということか〜」

// discuss.rubyonrails.orgより
console.log('current page: ', window.location.href)

document.addEventListener('click', function() {
  console.log('document click')
})

document.querySelectorAll('a').forEach(function(a) {
  a.addEventListener('click', function() {
    console.log('a click')
  })
})

「現代のWebフロントエンド環境ではDOM要素がちょくちょく再レンダリングされたりするので、addEventListener()とかで現在あるDOM要素をイベントリスナーに登録するみたいな方法は現代だともしかしたら厳しいかも?」「う〜む」「こういうので現在のDOMにあるものを登録しても、DOMが更新されたらイベントリスナーごと消えてしまうので、たぶん他の現代的なフレームワークでもうまくいかなそうな気がする🤔」

参考: EventTarget: addEventListener() メソッド - Web API | MDN

🔗 SprocketsからPropshaftに乗り換えたらサニタイザがHTML4版にフォールバックした(その後修正)

期待する振る舞い

sprockets-railsを使うかどうかにかかわらず、ActionView::Helpers::SanitizeHelper.sanitizer_vendorRails::HTML5::Sanitizerになるはず。new_framework_defaults_7_1.rbでもエラーにならない。

実際の振る舞い

  • 1.Railsを7.0から7.1にアップグレードする場合: sprockets-railsを削除してpropshaftに置き換えると、new_framework_defaults_7_1.rbのコードがuninitialized constant Rails::HTML例外を発生する(rails-html-sanitizerがデフォルトではrequireされていないため↓)。

rails/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults_7_1.rb.tt at v7.1.3.2 · rails/rails

  • 2. Rails 7.1でsprockets-railsを使わない場合: sprockets-railsではなくpropshaftを選択すると、Railsガイドに書かれている振る舞いと異なり、sanitizer_vendorRails::HTML4::Sanitizerが設定される。
    同issueより抜粋

参考: §3.11.21 config.action_view.sanitizer_vendor -- Rails アプリケーションの設定項目 - Railsガイド


つっつきボイス:「ruby-jp Slackでたまたま見かけたissueです」「お、Rails 7.1からAction TextのサニタイザではデフォルトでRails::HTML5::SafeListSanitizerが使われるようになった(ウォッチ20230802)けど、既存アプリをPropshaftにアップグレードしたらRails::HTML4::SafeListSanitizerにフォールバックしたのか」「Rails 8でPropshaftがデフォルトになることが決まったので(ウォッチ20240228)、開発もPropshaftがメインになった感じかな」「issueと同じ方がプルリクも出していますね↓」

Propshaft gem README(翻訳)

🔗 RubyアプリでActive RecordとSequelのどちらを使うか


つっつきボイス:「SequelはJeremy Evansさんがずっと手掛けている、Active Recordのオルタナ的なgemですね」「Active Recordだとbelongs_tohas_manyで書くようなところを、Sequelだとone_to_manymany_to_oneというDSLで書くのね↓: この違いは興味深い」

# 同記事より
# models/product.rb

class Product < Sequel::Model
  one_to_many :orders
end

# models/order.rb

class Order < Sequel::Model
  many_to_one :product
end

# クエリ
product_orders_under_20 = DB[:orders].join(:products, id: :product_id).where { price < 20 }

「Sequelだと楽観的ロックをこんなふうに書けるのか↓」「Sequelが好きな人なら、Rails以外のRubyアプリでSequelを使うのは普通にありだと思います👍」

# 同記事より
# invoice.rb

class Invoice < Sequel::Model
  plugin :optimistic_locking
end

jeremyevans/sequel - GitHub

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

🔗 その他Rails


つっつきボイス:「3/14(木に)Hotwire Loveイベントがあるそうです」「既存アプリを新しいTurbo 8に対応させる話題なんですね」「盛り上がってますね〜」

🔗Ruby

🔗 Rubyからシリアルポートにアクセスする(Ruby Weeklyより)

tenderlove/uart - GitHub


つっつきボイス:「tenderloveさんがシリアルポートで遊んでみた記事です」「懐かしい、UARTは自分も使ったことありますよ」「コードで使っているuart gemもtenderloveさん作なんですね↓」

参考: UART - Wikipedia

# 同記事より
require "uart"

MASK = (~(3 << 14)) & 0xFFFF

UART.open ARGV[0], 115200 do |serial|
  # turn on heartbeat
  serial.write "<HEARTBEAT1>>"

  loop do
    if serial.wait_readable(2)
      count = ((serial.readbyte << 8) | serial.readbyte) & MASK
      p count
    else
      $stderr.puts "oh no, something went wrong!"
      exit(1)
    end
  end
ensure
  # make sure to turn off heartbeat
  serial.write "<HEARTBEAT0>>"
end

「あれ、シリアル接続といえばRS-232Cは何を指すんでしたっけ?」「RS-232C自体はむかーしのPCに付いてたようなコネクタの規格のことで、広義のシリアル通信としてはRS-232Cでないものもあります: たとえばArduinoとかで使われてるようなマイコンだと、特定のピンをUART出力に割り当てることでそこからシリアルコンソールを取れたりしますが、こういうシリアルコンソール用のピンは基板上のパターンにだけ出ていたりするので、RS-232Cコネクタを使わないシリアル通信の口だったりします」

参考: RS-232 - Wikipedia

「基板によってはシリアルポートにアクセスすることでfastbootのプロンプトを取ってファームウェアを流し込んだりとか楽しいことができたりしますね」「そうそう、M5Stackあたりを触り始めると結局そうやって遊んだりしてます😆」

参考: M5Stack — スイッチサイエンス

🔗 Ruby「公案」(Ruby Weeklyより)


つっつきボイス:「Koanって何かと思ったら禅の公案のことみたい」「サイトはWasmで動くRubyクイズサイトなんですね」「英語圏の禅文化好きって昔からあるけど今も根強いですね」

参考: 公案 - Wikipedia


つっつき後に以下のツイートを見つけました↓。Ruby Koansは実は昔からあって、それをブラウザ版に移植したんですね。

🔗 Rubyで乱数を生成するとき(Ruby Weeklyより)


つっつきボイス:「記事は定番の話ですが、Rubyで乱数が必要なときはKernel#randとかではなくsecurerandom gemを使うべきですね(追記2024/03/18: ご指摘に基づいて文面と見出しを修正しました)」「ちなみに言語付属のライブラリで、数値としての乱数だけでなくhexやUUID、BASE64形式のフォーマットまでしてくれるのは結構ありがたいですよ😋↓」

# 同記事より
require "securerandom"

SecureRandom.alphanumeric    # "tpEnoWgScSJRU3YB"
SecureRandom.base64          # "0jHnJ7Yx5oTW0OY+YKgUog=="
SecureRandom.hex             # "b51372ee8b93eb3e1f0035d9300c3e97"
SecureRandom.rand            # 0.6053942880507039
SecureRandom.urlsafe_base64  # "OTHNscnomrNjjT0g_dzpdw"
SecureRandom.uuid            # "f6f54bd8-fc5a-483f-8909-05428dea2290"

参考: class Random (Ruby 3.3 リファレンスマニュアル)
ruby/securerandom - GitHub

🔗言語/ツール/OS/CPU

🔗 南京錠と木製からくり計算機


つっつきボイス:「南京錠のようなものを論理回路に見立てる遊びって昔からときどき目にしますね」

「直接関係ないけど、木で計算機を作る人を実際に見たことあったのを思い出しました↓」「お〜これはすごい!」「ちゃんと動くんですね」「レタリングや仕上げも丁寧なのが素晴らしいです」

参考: 「からくり計算器」「ゲームボーイシンセサイザー」「手のひらサイズお絵かきマシン」──“自作”の祭典「Maker Faire Tokyo 2019」で見た個性的な作品たち(1/2 ページ) - ITmedia NEWS
参考: 山宮隆 | Ogaki Mini Maker Faire 2022
参考: カラクリ計算器とは何か? - 言語ゲーム


後編は以上です。

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

週刊Railsウォッチ: Rails 8に入るSolid Cacheほか(20240312前編)

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

Ruby Weekly


### Ruby on Rails Discussions


CONTACT

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