From: Makoto Kishimoto Date: 2011-08-03T10:54:06+09:00 Subject: [ruby-dev:44338] [Ruby 1.9 - Feature #4788] resolv.rb refactoring Issue #4788 has been updated by Makoto Kishimoto. 元の問題は、lib/resolv.rb が、TCP へのフォールバックに対応して、その際に make_requester --> make_udp_requester という名前の変更があったために、 (公開インターフェースではない)それに依存していたコードが動かなくなった、 というものです。 しかし、make_requester のような内部の非常に低いレイヤにあるメソッドに rubydns ライブラリのコードが依存していた理由は、DNS#each_resource メソッド中に、個々のリソースを取得するコードが一体不可分に含まれてしまって いるため、DNS プロキシのようなものを作る場合、each_resource メソッド中の リソース取得部分のコードの duplicate が、このようなライブラリの実装において 不可避であったためです。 パッチで示したように、リソース取得部分を切り離し、また、一種のコールバックで ある extract_resources を、現状のハードコーディング状態から抽象化する リファクタリングによって、ライブラリ側でのコード duplicate が必要なくなります。 パッチで追加される fetch_resource メソッドのユースケースとして、 ライブラリ側のコードがどうなるかというパッチを示します。 --- resolv.rb.orig 2011-05-27 18:15:59.000000000 +0900 +++ resolv.rb 2011-08-03 10:38:43.000000000 +0900 @@ -24,6 +24,13 @@ # This allows such responses to be passed upstream with little or no # modification/reinterpretation. def query(name, typeclass) + if respond_to?(:fetch_resource) then + fetch_resource(name, typeclass) do |reply, reply_name| + return reply, reply_name + end + return + end + lazy_initialize requester = make_requester senders = {} ---------------------------------------- Feature #4788: resolv.rb refactoring http://redmine.ruby-lang.org/issues/4788 Author: Makoto Kishimoto Status: Open Priority: Normal Assignee: Akira Tanaka Category: lib Target version: 1.9.x このようなモンキーパッチが(私のコードではありませんが) https://github.com/ioquatix/rubydns/blob/master/lib/rubydns/resolv.rb #3835 ( [ruby-core:32407] )の結果、動かなくなっていたのでパッチを検討していたわけですが、 結論としてresolv.rbに以下のようなリファクタリングを施すのがいいのではないかと考えました。 パッチを添付します。 ---- diff --git a/lib/resolv.rb b/lib/resolv.rb index 1e18893..e9c2432 100644 --- a/lib/resolv.rb +++ b/lib/resolv.rb @@ -491,6 +491,12 @@ class Resolv # #getresource for argument details. def each_resource(name, typeclass, &proc) + each_resource_(name, typeclass) {|reply, reply_name| + extract_resources(reply, reply_name, typeclass, &proc) + } + end + + def each_resource_(name, typeclass) lazy_initialize requester = make_udp_requester senders = {} @@ -517,7 +523,7 @@ class Resolv # response will not fit in an untruncated UDP packet. redo else - extract_resources(reply, reply_name, typeclass, &proc) + yield(reply, reply_name) end return when RCode::NXDomain -- http://redmine.ruby-lang.org