Skip to content

Commit 44b6bff

Browse files
committed
Narrow Resolv::DNS resource methods by typeclass via bounded generic
`Resolv::DNS#getresource` / `#getresources` / `#each_resource` / `#extract_resources` accept a typeclass argument (e.g. `Resolv::DNS::Resource::IN::MX`) that fully determines the returned resource subclass. The signatures returned the upper bound `Resolv::DNS::Resource`, dropping that information; callers using subclass-specific methods like `MX#exchange` then need a downcast. Use a bounded type parameter (`[T < Resolv::DNS::Resource]`) so the return / block parameter tracks the typeclass: def getresources: [T < Resolv::DNS::Resource] (dns_name, singleton(T)) -> Array[T] | (dns_name, singleton(Resolv::DNS::Resource::ANY)) -> Array[Resolv::DNS::Resource] `Resolv::DNS::Resource::ANY` does not inherit from `Resource` (it sits parallel under `Query`), so the wide overload is kept alongside as the fallback for `ANY` queries. `fetch_resource` also takes a typeclass argument but does not return or yield a `Resource`, so it is left as-is.
1 parent fcc1685 commit 44b6bff

1 file changed

Lines changed: 8 additions & 4 deletions

File tree

stdlib/resolv/0/resolv.rbs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,11 @@ class Resolv::DNS
218218
# Iterates over all `typeclass` DNS resources for `name`. See #getresource for
219219
# argument details.
220220
#
221-
def each_resource: (dns_name name, singleton(Resolv::DNS::Query) typeclass) { (Resolv::DNS::Resource) -> void } -> void
221+
def each_resource: [T < Resolv::DNS::Resource] (dns_name name, singleton(T) typeclass) { (T) -> void } -> void
222+
| (dns_name name, singleton(Resolv::DNS::Resource::ANY) typeclass) { (Resolv::DNS::Resource) -> void } -> void
222223

223-
def extract_resources: (Resolv::DNS::Message msg, dns_name name, singleton(Resolv::DNS::Query) typeclass) { (Resolv::DNS::Resource) -> void } -> void
224+
def extract_resources: [T < Resolv::DNS::Resource] (Resolv::DNS::Message msg, dns_name name, singleton(T) typeclass) { (T) -> void } -> void
225+
| (Resolv::DNS::Message msg, dns_name name, singleton(Resolv::DNS::Resource::ANY) typeclass) { (Resolv::DNS::Resource) -> void } -> void
224226

225227
# <!--
226228
# rdoc-file=lib/resolv.rb
@@ -299,7 +301,8 @@ class Resolv::DNS
299301
# Returned resource is represented as a Resolv::DNS::Resource instance, i.e.
300302
# Resolv::DNS::Resource::IN::A.
301303
#
302-
def getresource: (dns_name name, singleton(Resolv::DNS::Query) typeclass) -> Resolv::DNS::Resource
304+
def getresource: [T < Resolv::DNS::Resource] (dns_name name, singleton(T) typeclass) -> T
305+
| (dns_name name, singleton(Resolv::DNS::Resource::ANY) typeclass) -> Resolv::DNS::Resource
303306

304307
# <!--
305308
# rdoc-file=lib/resolv.rb
@@ -308,7 +311,8 @@ class Resolv::DNS
308311
# Looks up all `typeclass` DNS resources for `name`. See #getresource for
309312
# argument details.
310313
#
311-
def getresources: (dns_name name, singleton(Resolv::DNS::Query) typeclass) -> Array[Resolv::DNS::Resource]
314+
def getresources: [T < Resolv::DNS::Resource] (dns_name name, singleton(T) typeclass) -> Array[T]
315+
| (dns_name name, singleton(Resolv::DNS::Resource::ANY) typeclass) -> Array[Resolv::DNS::Resource]
312316

313317
def lazy_initialize: () -> untyped
314318

0 commit comments

Comments
 (0)