Ruby 4.0+ での log_regexp_timeout= 再定義警告を抑制
Ruby 4.0 以降、require "ruby_llm" を実行すると log_regexp_timeout= の再定義に伴う警告が出力されます。本稿では、その警告を抑制するための実装変更と設計判断を解説します。
背景
Ruby 4.0+ では同名メソッドの再定義に対してデフォルトで警告が出力されるため、require "ruby_llm" 時に method redefined; discarding old log_regexp_timeout= が表示されていました。RubyLLM::Configuration の option メソッドは内部で attr_accessor を呼び出し、log_regexp_timeout= アクセサを自動生成します。その直後に同名のカスタム setter が手動で定義されているため、メソッドテーブルに二つの定義が重なり、Ruby 4.0+ で警告が顕在化しました。この警告は機能上の問題ではなく、利用者にとって不要なノイズとなります。
警告の抑制が求められた背景は、ライブラリ利用時の出力をクリーンに保ち、テスト結果への影響を防ぐことにあります。
この課題は、既存 API の挙動を変えずに実装上の調整だけで解決できると判断されました。
技術的な変更
PR #721 では remove_method を利用して自動生成されたアクセサを削除し、カスタム setter を再定義する手順が追加されました。この変更により Ruby が再定義を検知できず、警告が出力されなくなります。
@@ -81,6 +81,7 @@ def instance_variables
super.reject { |ivar| ivar.to_s.match?(/(_id|_key|_secret|_token|_credential_provider)$/) }
end
+ remove_method :log_regexp_timeout=
def log_regexp_timeout=(value)
if value && !Regexp.respond_to?(:timeout)
RubyLLM.logger.warn("log_regexp_timeout is not supported on Ruby #{RUBY_VERSION}")
remove_method :log_regexp_timeout= が追加されたことで、option が生成した元のアクセサが明示的に除去され、続くカスタム実装が唯一の定義となります。その結果、Ruby の再定義警告ロジックはトリガーされません。
テストコードも同時に拡充され、require "ruby_llm" 時に警告が出力されないことを自動的に検証しています。
describe 'method redefinition warnings' do
it 'does not emit method redefined warning for log_regexp_timeout=' do
warnings = `#{RbConfig.ruby} -W -e 'require "ruby_llm"' 2>&1`
expect(warnings).not_to include('method redefined')
end
end
変更は lib/ruby_llm/configuration.rb とテストファイルのみで完結し、他のロジックや公開 API には影響を与えません。
設計判断
本修正は Ruby 標準機能である remove_method を用いた最小侵襲のアプローチです。option メソッド自体やアクセサ自動生成ロジックを改変せず、既存の設定キーや API をそのまま維持できました。
言語レベルのメソッド削除は安全に使用でき、追加の依存やラッパーコードを導入しない点が採用理由となります。これにより後方互換性が保証され、利用者への影響を最小限に抑えられました。
設計上の焦点は「警告抑制だけを実現し、既存の設定フローを変えないこと」でした。その結果、コードベースの複雑化を防ぎつつ、問題の根本を解決できました。
まとめ
PR #721 により、Ruby 4.0+ 環境で require "ruby_llm" 時に出ていた log_regexp_timeout= 再定義警告が完全に抑制されました。実装は remove_method の一行追加と回帰テストの追加だけで、ライブラリの公開 API や他の挙動には一切変更を加えていません。これにより利用者はクリーンな起動出力を得られ、同様の再定義警告が将来的に発生した場合の対策指針としても有用です。