Automatic Ruby を約 10 年ぶりに本格的にモダナイズしました。現在の開発版は Ruby 3.3 から 4.0 をサポートし、CI では Ruby 3.3、3.4、4.0 を継続的に検証する構成になっています。
ただし、この記事を書いている時点では次期版の v26.08 はまだリリースしていません。RubyGems に公開されている版は古いままなので、この記事では RubyGems 版をインストールせず、GitHub から git clone した開発版を前提にします。2015 年以来の本格的な更新になることは、現在のバージョン履歴にも記録しています[1]。
Automatic Ruby とは何か
Automatic Ruby は、Ruby で書かれた汎用的な自動処理フレームワークです[2]。
Automatic Ruby のリポジトリは、次のとおりです。
何か一つの用途を実現するアプリケーションではありません。処理の単位をプラグインとして用意し、それを YAML の Recipe に上から順番に並べます。フレームワーク本体は Recipe を読み込み、前のプラグインが返したデータを次のプラグインへ渡していきます。
現在の README にある最小例は、次のような形です。
plugins:
- module: SubscriptionFeed
config:
feeds:
- https://www.ruby-lang.org/en/feeds/news.rss
- module: PublishMarkdown
config:
file: ~/.automatic/markdown/feeds.md
mode: append
この Recipe では、SubscriptionFeed が Ruby のニュースフィードを取得し、その結果を PublishMarkdown が Markdown ファイルへ書き出します。
処理の流れだけを抜き出すと、次の 2 段です。
SubscriptionFeed
|
v
PublishMarkdown
フィードの取得先や出力先を変えるために、フレームワーク本体を書き換える必要はありません。プラグインを差し替えるか、別のプラグインを Recipe に追加します。
Automatic Ruby が提供している中核は、プラグインの共通契約、プラグイン間で受け渡すパイプライン、名前からプラグインを読み込む仕組みです。現在もフレームワーク本体は 700 行未満に抑えています[2]。
つまり「Automatic Ruby で何ができるのか」という問いには、「プラグイン次第」という答えになります。情報を取得する、絞り込む、並べ替える、重複を除く、ファイルへ保存する、外部サービスへ渡す、といった処理を組み合わせられます。独自のプラグインを書けば、その処理も同じパイプラインへ組み込めます。
Plagger を覚えていますか
Automatic Ruby の設計には、Plagger の影響があります。
Plagger は Perl で書かれたフィードアグリゲーターで、プラグインを組み合わせて情報の取得、加工、出力をつなげる仕組みを持っていました。約 20 年前、フィードを中心とした自動処理の道具として名前を見かけた人もいると思います。Plagger の特徴として、プラグインを組み合わせて処理を拡張できることが挙げられています[3]。
Plagger のリポジトリは、次のとおりです。
Automatic Ruby を作ったのは 2012 年です。Plagger の Recipe とプラグインの考え方を Ruby で扱いたくなり、同じように処理をパイプラインとして組み立てられるフレームワークを作りました。
2014 年には、Automatic Ruby で新聞社のフィードを取得し、重複を除いて Fluentd へ渡す例を Qiita に書いています。その記事でも、Recipe の書き方が Plagger に影響を受けていることを説明していました[4]。
当時の例は次のような流れでした。
フィードを取得
|
v
保存済みの記事を除外
|
v
Fluentd へ出力
現在は Markdown への出力も標準で用意していますが、フレームワークの基本的な考え方は変わっていません。
Ruby 4.0 で最小構成を動かす
現在の開発版は Ruby 3.3 から 4.0 を対象にしています。GNU/Linux と macOS を想定しており、Windows はサポートしていません[2]。
まず Ruby のバージョンを確認します。
ruby -v
次にリポジトリを取得します。
git clone https://github.com/id774/automaticruby.git
cd automaticruby
開発版を最小構成でセットアップします。
bundle install
ここでいう最小構成は、Automatic Ruby 本体を動かし、テストできる構成です。フレームワーク本体の実行依存に加えて rake、rspec、simplecov などの開発用依存は入りますが、特定のプラグインだけが必要とする sqlite3、nokogiri などは入りません。
まずコマンドが起動することを確認します。
bundle exec bin/automatic --version
テストも実行できます。
bundle exec rake
checkout から実行する場合は、以後の automatic コマンドを bundle exec bin/automatic として実行します。
最小構成だけで Markdown を生成する
最初の動作確認には、データベースも外部サービスの認証情報も必要ありません。
ユーザー用ディレクトリを作ります。
bundle exec bin/automatic scaffold
これにより ~/.automatic が作られ、サンプルの Recipe も配置されます。
次の Recipe を実行します。
bundle exec bin/automatic -c ~/.automatic/config/example/feed2markdown.yml
生成された Markdown を確認します。
sed -n '1,80p' ~/.automatic/markdown/feeds.md
このサンプルが使うのは SubscriptionFeed と PublishMarkdown だけです。最小の bundle install だけで実行できます[2]。
この Recipe は、同じ項目を既に処理したかどうかを記録しません。そのため、同じ Recipe をもう一度実行すると同じ項目が追記されます。ここまでは意図した最小例です。
定期実行するなら、次に重複排除を追加します。
必要なプラグインの依存だけ後から追加する
Automatic Ruby では、すべてのプラグインの依存ライブラリを最初から入れない方針に変えました。
例えば StorePermalink を使って処理済みの項目を SQLite に記録する場合は、store グループだけを追加します。
bundle config set --local with store
bundle install
これで activerecord と sqlite3 が追加されます。
Recipe では取得と出力の間に StorePermalink を置きます。
plugins:
- module: SubscriptionFeed
config:
feeds:
- https://www.ruby-lang.org/en/feeds/news.rss
- module: StorePermalink
config:
db: feed2markdown.db
- module: PublishMarkdown
config:
file: ~/.automatic/markdown/feeds.md
mode: append
2 回目の実行では既に記録された項目が後続へ渡らないため、新しい項目だけを Markdown へ追加できます。
HTML を扱うプラグインや Store 系のプラグインを使わないのであれば、その依存ライブラリをインストールする必要はありません。全プラグイン向けの依存を一度に入れる構成も用意していますが、通常は最小構成から始め、必要になったものだけを追加するほうが構成を把握しやすくなります。
なお、checkout では bundle exec を使うため、単に別途 gem install sqlite3 などを実行するのではなく、Bundler のグループへ追加します。実行時に見える依存関係を Gemfile 側で管理するためです。
約 10 年前のコードを、そのまま Ruby 4.0 で動かしたわけではない
今回の作業は、Ruby のバージョン番号だけを書き換えたものではありません。
残したものと変えたものを分けると、今回のモダナイゼーションの方針が分かりやすくなります。
| 残したもの | 現代化したもの |
|---|---|
| YAML の Recipe | Ruby 3.3 から 4.0 への対応 |
| プラグインを順番に実行する構造 | 非推奨になった Ruby API |
| 一つのパイプラインを受け渡す契約 | 依存ライブラリと Bundler 構成 |
| ユーザー独自プラグインの仕組み | CLI とエラー処理 |
| 小さなフレームワークという方針 | YAML 読み込み、HTTP、TLS などの安全性 |
| Recipe から処理を組み立てる考え方 | テスト、CI、ドキュメント |
モダナイゼーションで重要だったのは、昔のコードを一字一句残すことではありませんでした。Recipe、プラグイン、パイプラインという設計上の契約を残し、その周囲にある実装を現在の Ruby とライブラリへ合わせることでした。
古い API を置き換える過程では、長く眠っていた不具合も見つかりました。例えば、ネットワークアクセスの間隔を空けるための interval が、実際には待機していなかった問題も修正しています[5]。
使えなくなったプラグインは残さない
約 10 年の間には、Ruby だけでなく外部サービスも変わっています。
今回、従来の 45 プラグインを一つずつ確認しました。現在は 34 プラグインを残しており、内訳は Supported が 23、外部サービスやコマンドなどを利用者側で用意する Supported (external) が 10、Needs rework が 1 です[5]。
一方で、サービスや API が既に存在しない 11 プラグインは削除しました。Twitter、Pocket、HipChat、Google Calendar、livedoor Weather など、当時は意味があっても現在は同じ方法では利用できない連携が含まれています。
古いソフトウェアを現代化するとき、すべての機能を残すことが互換性ではありません。既に存在しない外部サービスへの連携を形だけ残すと、動くように見えるコードと実際に利用できる機能がずれてしまいます。
残す設計と捨てる連携を分けることも、モダナイゼーションの作業でした。
finance と finance-dashboard も現代化した
Automatic Ruby の前後には、ほかの自作ソフトウェアも現代化しています。
finance は、株価データを取得してテクニカル指標や機械学習モデルを計算し、CSV やチャートを生成するバッチ処理です。2015 年当時の構成から、現在の Python パッケージ、依存ライブラリ、テスト構成へ整理しました[6]。
finance-dashboard は、その生成物を表示するダッシュボードです。こちらは Sinatra で書かれていた実装を Python の FastAPI と Jinja2 へ置き換えました[7]。
関連するリポジトリは、次の 2 つです。
現在は、分析する側と表示する側を次のように分けています。
市場データ
|
v
finance
|
v
CSV / TXT / PNG
|
v
finance-dashboard
Automatic Ruby とは用途も言語構成も異なりますが、共通しているのは、昔のコードを全面的に別物へ作り直すのではなく、現在も意味のある役割と境界を確認してから周囲を更新したことです。
AI エージェントの時代に、自分の古いソフトウェアを見直す
以前なら、約 10 年止まっていたリポジトリを再び触るにはかなりの時間が必要でした。
コードだけを直せば終わりではありません。現在の言語処理系で動くか、依存ライブラリは存続しているか、外部 API は変わっていないか、テストは現在の環境で意味を持つか、CI は動くか、インストール方法は妥当か、ドキュメントは現在の実装と一致しているかを確認する必要があります。
AI エージェントがリポジトリを読み、調査、実装、テスト、修正まで一つの作業単位として扱えるようになったことで、この種の棚卸しを現実的な作業量で進めやすくなりました。以前書いた「最新 AI は何が変わったのか 2026」でも、Claude Code を含む開発エージェントが、コード生成だけでなくリポジトリの理解、変更、検証まで担うようになっている点を整理しています[8]。
今回も、AI に「古いコードを新しくして」とだけ頼んだわけではありません。
例えば Automatic Ruby では、Recipe とプラグイン契約は残す、古い外部サービスは実在性を確認する、死んだ連携は削除する、最小インストールでは不要な依存を入れない、といった判断を先に置きました。その判断に沿って、コード、テスト、CI、依存関係、ドキュメントを順番に更新しています。
AI に任せられる作業が増えても、何を残し、何を捨て、どこまでを互換性として守るかは自動的には決まりません。以前書いた「AI に任せる前に、人間が残すべき判断」という話は、古いソフトウェアのモダナイゼーションでもそのまま当てはまりました[9]。
関連する既稿としては、次の 2 本があります。
顧客のモダナイゼーションを考える前に、自分のものを直す
今回、自作ソフトウェアを続けて現代化した理由は単純です。
レガシーシステムのモダナイゼーションは、今後ますます AI エージェントの重要な仕事になります。顧客の古いシステムをどう変えるべきか考えるのであれば、その前に自分が 10 年以上前に書いたコードを題材にして、実際にどこまで直せるのかを試しておきたいと考えました。
自分で書いたソフトウェアなら、当時なぜその設計にしたのかもある程度分かります。それでも、現在の目で読むと、残す価値のある設計と、単に当時の環境へ依存していた実装は別のものとして見えてきます。
Automatic Ruby では、Recipe とプラグインによるパイプラインは今でも使えると判断しました。一方、既に終了したサービスとの連携や、現在では危険な通信方法、古いライブラリ API まで残す理由はありませんでした。
この切り分けを実際のコードで経験できたこと自体が、今回のモダナイゼーションで得られたものです。
レガシーなシステムを最新にするのは面白い
新しいソフトウェアをゼロから作る仕事とは違い、モダナイゼーションには既にある設計との対話があります。
約 10 年前のコードを見ると、古くなった書き方や依存関係がある一方で、現在でもそのまま使える考え方も残っています。全部捨てて書き直すのでもなく、無理に全部残すのでもなく、どこに境界を引くかを決めていく仕事です。
Automatic Ruby は、現在も「Recipe にプラグインを並べ、一つのパイプラインを順番に処理する」という昔の設計のままです。その周囲を Ruby 4.0、現在の依存ライブラリ、CI、テスト、ドキュメントへつなぎ直しました。
AI エージェントによって、このような古いソフトウェアをもう一度調べ、動かし、整理するためのコストは大きく下がりました。長く止まっていた自分のコードを、現在でも使えるソフトウェアへ戻す。
レガシーなシステムを最新にするのは、やりがいのある仕事だと思います。
参考文献
- id774, automaticruby Repository Version History(2026-08-15). https://github.com/id774/automaticruby/blob/master/doc/VERSIONS
- id774, Automatic Ruby(2026-08-15). https://github.com/id774/automaticruby
- Wikipedia contributors, Plagger(2025-04-24). https://ja.wikipedia.org/wiki/Plagger
- id774, Fastladder または Automatic Ruby + Fluentd を利用してフィードを購読する(2014-10-17). https://qiita.com/ynakayama/items/c07c92031802b8d4c3e2
- id774, Recipes and plugins(2026-08-15). https://github.com/id774/automaticruby/blob/master/doc/PLUGINS.md
- id774, finance(2026-08-15). https://github.com/id774/finance/blob/master/README.md
- id774, Finance Dashboard(2026-08-15). https://github.com/id774/finance-dashboard/blob/master/README.md
- id774, 最新 AI は何が変わったのか 2026(2026-07-03). https://blog.id774.net/entry/2026/07/03/4937/
- id774, AI に任せる前に、人間が残すべき判断(2026-06-21). https://blog.id774.net/entry/2026/06/21/4912/