Emacs 環境を刷新した

金曜日の終業間際に Emacs 環境が壊れてしまい。週末はその復旧にあてがった。

おそらくアップグレードした Emacs 29 と Helm の噛み合わせが悪くなったことが原因 (かもしれない) 。

もともといい加減 Helm から Ivy に変更したかったのと、el-get もあまりうまく活用できている感じではなかったことから、Emacs 環境を再整備する機会として 8 年ぶりに init.el をスクラッチでリライトすることにした。@onk 経由で知った言葉を借りれば、これもまたソフトウェア式年遷宮みたいなものかもしれない。

下環境構築メモ。

  • まず anything.el の流れのものがないとどうにもならないので、Helm に変わり Ivy を入れる。2018年くらいに @elct9620 から Ivy が良さそうという話を聞いてからかなり時間が経っていた
  • recentf もないとどうにもなので、Ivy と連携して動くようにする
  • eglot 設定をする
  • git-gutter がないと git のソースコード差分がわからないので設定する
  • ghq と Ivy を連携して動くようにする
  • (global-set-key (kbd "C-h") 'delete-backward-char) とかいつものは過去の dotfiles から持ってくる

などなど詳細は割愛するが諸々手を加えていた。

一番の変更点はターミナル (iTerm2) を含めて Emacs のテーマも白背景から黒背景にしたこと。その昔「ターミナルの黒い画面が怖い」というものへのネタとして「画面白いから怖くないよ」という @kenchan の返しが当時面白かったので白い画面にしていたけれど、どうもその後ウケをうまく伝えられなかったので 10 年ぶりくらいに黒い画面にした。

この10年の白い画面生活からのフィードバックとしては、いろいろなターミナルツールが黒い画面を前提にしたデフォルト配色になっているので、実は白い画面は世の中のデフォルト配色と相性が良くなかったりしたのはノウハウとして伝えられることかもしれません。

なお、この機会に VS Code へという考えはありませんでした。M-x Forever!

RuboCopのメンテナンスポリシーを更新した

以下のように RuboCopのメンテナンスポリシーを更新することにした。

docs.rubocop.org

これまでは Ruby バージョンの EOL 後に1年猶予をもってから、RuboCop のランタイムサポートからもドロップしていた。つまり Ruby 2.6 が EOL を迎えた際は、その 1 年後に Ruby 2.6 を RuboCop のランタイムサポートから落としていた (ドロップするのはランタイムバージョンであり、Ruby 2.0 までバージョンを遡っての解析はできます) 。今回その方針を変えて、Ruby 2.7 ランタイムサポートを延長する決定をしたことになる。

理由としては大きく2つあり、ひとつは Ruby 2.7 から Ruby 3.0 へのメジャーバージョンアップについて、 (いわゆる言語コミュニティの分断というほどのものではなく、いつものレベル感の延長線上で) アップグレードしている世界としていない世界が二極化していること。まあ、これは毎度のことかもしれないけれど、今回はメジャーということもありバッサリといつもどおりとせずに決断は慎重にしようと考えていた。

もうひとつが上記の支えになったというか、理由づけの後押しになったもので、現時点での Rails の最新安定版の 7.1 が Ruby 2.7 をサポートしているということ。

こういった理由から Rails のメンテナンスポリシーで、少なくとも Rails 7.1 が "Bug Fixes" にカテゴライズされている間は Ruby 2.7 をランタイムサポートすることにした。

guides.rubyonrails.org

とはいえ古い Ruby バージョン向けには、今後ランタイム依存の新機能のバックポートなど (必要以上のものはし) ないため、各現場での Ruby アップグレードを進めていきましょう。

GemfileでのRubyバージョン指定を.ruby-versionから読む

Gemfile での Ruby バージョンの指定を、値の直書きではなく .ruby-version からの読み込みに変更する設定です。 https://github.com/rubygems/rubygems/pull/6876

例えば、Rails アプリケーションなんかで Gemfile に .ruby-version と同じ 3.3.0 を指定しているようであれば、以下のように記述できます。

-ruby '3.3.0'
+ruby file: '.ruby-version'

asdf に類するものを使っているようであれば、ruby file: '.tool-versions' と記します。 https://github.com/rubygems/rubygems/pull/6898

この設定によって Ruby のアップデート時のバージョンの更新ポイントを減らすことができます。

なお、古い Bundler ではこのオプションは使えないため、その場合は BUNDLED WITH の値を bundle update --bundler あたりで更新する必要があります。

 BUNDLED WITH
-   2.3.7
+   2.5.3

もし、古い環境で ruby File.read('.ruby-version').strip と Gemfile に書いているようであれば、新しい Bundler ではこんな感じで書くことができるのでここで紹介した DSL に沿っておくと良いと思います。

そんな感じの Bundler 小技でした。

ここからはおまけ。

これは RuboCop に入れれば良いのでは?と思った方は鋭い。以下の考慮点をどうするかで悩んでいるところ。

最初に考えるのは、この API に対応している Ruby 3.3 梱包のデフォルト Bundler だとしても、BUNDLED WITH が旧来のままだと ruby file: '.ruby-version' は書けない問題。ただし、これは BUNDLED WITH を見れば解決可。

で、本質的に難しいのは例えば CI 環境によっては .ruby-version のコピーが必要だと、ローカルで読めたファイルが CI で読み込みできずにエラーになることを防げません (つまり CI 環境への手入れが必要) 。そうなるとオートコレクトは提供せずに、このあたりはドキュメンテーションとする?そうすると、そこまで頑張ってまで Cop として入れるかというと、小技っぽい感じなのでやめておこうというのがいまのところ。過去の流れ も踏まえて、気が向いたらもう少し考えます。

2023年にしていたGitHub遊び

2015年から行なっている Write Code Every Day というか、GitHub に草を生やす活動は、2019 年から JST では途切れることなく続いている。去年 2022 年には rubocop org だけでも毎日草が生えるようにしようとしていて達成していた。

毎年同じ草の生やし方をしても面白くないので、近年はそんな感じで縛りルールを作って行なっている。

github.com

今年 2023 年は rubocop/rubocop リポジトリ単独だけでも毎日草を生やそうというか、rubocop/rubocop リポジトリに 365 日コミットを入れてみようと進めて達成した。365 日のコミットに対したもうけた縛りは以下の2つ。

  • コミットログのタイムスタンプを 365 日入れる
  • GitHub 上の commits で 365 日表示されるようにする

前者は git log に準じた日付を入れるだけなので問題ない。ひとつだけ気にしないといけないのは、マージされるか微妙なプルリクエストを出すようなことがある場合には、それとは別に確実に master に入れることができる同じ日のコミットを設けておくということ。保険重要。

後者はちょっとクセがある。GitHub の commits に表示されるものは、git log のタイムスタンプに準じるとは限らない。ちょっと複雑なので条件を以下に書いておく。

  • マージコミットを作るケースでは、マージ元の PR に紐づくコミットが commit された日付に準じる。これの何に気を配るケースがあるかというと、対応すべきレビューコメントがついて修正 squash の後に force-with-lease した際には、その日付が commits に残る。レビューコメントもそうだし、master ブランチとのコンフリクトが発生してその解消が必要な際も同様。つまり git log のタイムスタンプが commits に表示されるとは限らない点に注意が必要
  • squash merge のケースでは、squash merge した日付として commits には表示される。つまり 1月1日にコミットして PR を開いたとして、1月3日に squash merge されると 1月3日の commits として表示される

後者も即日マージされれば気にすることはないけれど、レビューを受けた方が良いときは master 直ではなくプルリクエストにしているわけで、そういったケースでは保険を気に掛ける必要がある。

こんな感じでいくつか気を配らないといけないポイントがあるので、マージコミットも 365 日のコミットに含めることを OK とした。マージコミットは git log ならびに GitHub の commits のいずれにもそのタイムスタンプで反映されるのでたいへん便利。

GitHub 上の見た目はタイムゾーンに依存するが、そこは JST でのみクリアできれば良いものとしたのも難易度を易しい方に倒した点としてある。

という GitHub 遊びを 2023 は行なっていた。地球上に同じような縛りルールで遊んでいる人が他にいるかわからないけれど GitHub 遊びの参考までに。

vscode-rubocopをOpen VSX Registryに公開した

RuboCop LSP の VS Code 拡張である vscode-rubocopVS Code ベースの VSCodium や Eclipse Theia といった IDE で使いたいので、Open VSX Registry に公開してもらいたいというリクエストがあって対応しました。

https://open-vsx.org/extension/rubocop/vscode-rubocop

VSCodium や Eclipse Theia といった VS Code ベースのオルタナティブ IDE は、Microsoft の規約の関係で Visual Studio Marketplace への vsix 配布だと使えないらしく、Eclipse Foundation が管理している Open VSX Registry 経由で使うものというのが理由。VS Code すらふだん使いではないので知らなかったけれど、権利の関係でいろいろあるらしい。

そんな感じで Open VSX Registry への配布にあたり、Visual Studio Marketplace 同様に Open VSX Registry でも rubocop という名前空間で配布することにしたけれど、名前空間に対する利用者の正当性を以下のように主張しないと警告が出続けるっぽかったのでそちらはこんな感じのイシューで依頼していた。

github.com

Eclipse Foundation の中の人かな?人力対応大変な気がするけれど、それはそれとして早速承認されてシールド対応済みです。

いちおう書いておくと Open VSX Registry への配布物は Visual Studio Marketplace と同じものです。私自身は VSCodium や Eclipse Theia といった VS Code ベースの IDE は使ったことがないし、なんなら CI でもまわしていないので、VS Code 互換のものについては動くだろう、、、といった感じでご活用ください。

RWCスポンサートークで構文解析器研究部のスーパーLTした

RubyWorld Conference 2023 に参加した。オフライン参加の現地参加は4年ぶり。聖地「やぁ」や、かつて @kakutani に教えてもらったうどん屋の「のび太」がなくなっていたりと変化はあったものの、久しぶりの松江も楽しめました。

勤務先の永和システムマネジメントでは「ESMスーパーライトニングトークス」というタイトルで、1人80秒のスーパーライトニングトークスをスーパーライトニングトーカー名義の @m_pixy, @ima1zumi, @maimux2x, @fugakkbn, @koic, @junk0612, @S-H-GAMELINKS で開催しました。当初スポンサートークとしての企画ギリギリを突いてみた感じではあるものの、終わってみればスポンサートークのあり方について可能性を引き出せたんじゃなかなとそれなりに自負しています。

ちなみに ESM スーパーライトニングトーカーズといった名義提案は私がしたもので、元ネタは『パーフェクトRuby』の Ruby サポーターズです。それぞれ名前付けによって、当日まで発表内容と発表者を遅延できる抽象化技術ですね。

自分のスーパー LT は以下。

いくつかテーマを考えた中で、この後の構文解析器研究部の部員への流れとなる話にすることにしたのが今回。実は話の全体像は「大阪Ruby会議03」の飲み会で話をした「構文解析器研究部の生い立ち」がベースになっています。

少し真面目な話、プロジェクトやセクション間でメンバー交流が断絶気味になるというコンテキストは、いろいろな組織で見られているものだと思っていて、「GC研究部」も含めたこういったアングラな部活動はそういった課題を解決する『組織パターン』としても昇華していけるものでは!?というような壮大なストーリーがその裏にはあったりします。そんな感じで松江行きの移動で『組織パターン』を読んでいたりしたのですが、いずれにせよ80秒で収まる話ではないので機会があれば、それはそれでまた今度。

RubyWorld Conference の公式 X でも、構文解析器研究部の部員募集中とアナウンスしてもらってありがとうございました。入社するともれなく入部資格が手に入るので、ぜひカジュアル面談希望などお声掛けください。

RubyWorld Conference 15 周年おめでとうございました。また来年。

『JavaScript Primer』を読んだ

JavaScript Primer』を読んだ。Web でも読めることは知っているものの、それなりにページ量が多いので Kindle で読もうということで電子書籍版とした。そして、書籍や記事で重要なのは誰が関わっているかというところで、実績と信頼の azu さんが著者のひとりということで優勝の一冊。

いわゆるモダンな JavaScript を手広くおさらいしたいという場合にオススメで、痒い所に手が届く親切な説明がされていて著者の温かみを感じるコンテンツです。

自分の場合は健康に良くないことは分かりつつ、就寝前にスマホ Kindle で読むことがあり「動かさないとよく分からん」「この場合はどんな挙動?」という気になりについて、iSH という iPhone アプリを使って動作検証を見たりする。

ish.app

iSH は Alpine Linux となるので、apk で Node.js のパッケージをインストールして iPhone アプリのターミナルで動かすことになる。Node.js に限らず apk でインストールして遊ぶこともできる。RubyKaigi 2023 でキックボクサーがデモに使っていた際には「おお」となったのも記憶に新しい。

個人的には、JavaScript ランタイムにおけるイベントループの非同期に関する動きについて、『ハンズオンNode.js』の2章あたりで、process.nextTick()queueMicroTask() の動きとあわせて補完しておくと理解が深まると思う。

JavaScript 本は何冊か読んでいるけれど、これはタイトルどおり『JavaScript Primer』としておすすめ。

互換性を重視する (ため古い機能を捨てられない) 言語でのプラクティスには、右手に ES6 以降の知識、左手に『リファクタリング 第2版』ということで、発見があるうちは何度でも Primer しよう。