From: Sam Roberts Date: 2005-01-31T11:31:48+09:00 Subject: 'example.com' == 'example.com.' => false... is this intended? Hi Tanaka, I don't understand why DNS::Name#== requires both to be absolute if one is. Is this really necessary/useful? It surprises me. Also, I have a set of comparison operations for Resolv::DNS::Name. I copied the style (and docs) from Module/hierarchy comparisons, because I think there is some similarity. Comments? If you will accept, I will send patch and changelog. Thanks, Sam Below is implementation, followed by unit test so you can see behaviour. # DNS names are hierarchical in a similar sense to ruby classes/modules, and the # comparison operators are defined similarly to those of Module. A name is # +<+ another if it is a subdomain. # www.example.com < example.com # -> true # example.com < example.com # -> false # example.com <= example.com # -> true # com < example.com # -> false # bar.com < example.com # -> nil # # Note that #== does not consider two names equal if they differ in whether # they are #absolute?, but #equal? considers only the label when comparing # names. class Name def inspect n = to_s n << '.' if absolute? return n end def equal?(name) n = Name.create(name) @labels == n.to_a end def related?(name) n = Name.create(name) l = length < n.length ? length : n.length @labels[-l, l] == n.to_a[-l, l] end def lt?(name) n = Name.create(name) length > n.length && to_a[-n.length, n.length] == n.to_a end # Summary: # name < other => true, false, or nil # # Returns true if +name+ is a subdomain of +other+. Returns # nil if there's no relationship between the two. def <(name) n = Name.create(name) return nil unless self.related?(n) lt?(n) end # Summary: # name > other => true, false, or nil # # Same as +other < name+, see #<. def >(name) n = Name.create(name) n < self end # Summary: # name <= other => true, false, or nil # # Returns true if +name+ is a subdomain of +other+ or is the same as # +other+. Returns nil if there's no relationship between # the two. def <=(name) n = Name.create(name) self.equal?(n) || self < n end # Summary: # name >= other => true, false, or nil # # Returns true if +name+ is an ancestor of +other+, or the two DNS names # are the same. Returns nil if there's no relationship # between the two. def >=(name) n = Name.create(name) self.equal?(n) || self > n end # Summary: # name <=> other => -1, 0, +1, nil # # Returns -1 if +name+ is a subdomain of +other+, 0 if # +name+ is the same as +other+, and +1 if +other+ is a subdomain of # +name+, or nil if +name+ has no relationship with +other+. def <=>(name) n = Name.create(name) return nil unless self.related?(n) return -1 if self.lt?(n) return +1 if n.lt?(self) # must be #equal? return 0 end end require 'test/unit' Name = Resolv::DNS::Name class TestDnsName < Test::Unit::TestCase def test_what_I_think_are_odd_behaviours # Why can't test against strings? assert_equal(false, Name.create("example.CoM") == "example.com") assert_equal(false, Name.create("example.CoM").eql?("example.com")) # Why does making it absolute mean they aren't equal? assert_equal(false, Name.create("example.CoM").eql?(Name.create("example.com."))) assert_equal(false, Name.create("example.CoM") == Name.create("example.com.")) end def test_CoMparisons assert_equal(true, Name.create("example.CoM").eql?(Name.create("example.com"))) assert_equal(true, Name.create("example.CoM") == Name.create("example.com")) assert_equal(true, Name.create("example.CoM").equal?("example.com.")) assert_equal(true, Name.create("example.CoM").equal?("example.com")) assert_equal(true, Name.create("www.example.CoM") < "example.com") assert_equal(true, Name.create("www.example.CoM") <= "example.com") assert_equal(-1, Name.create("www.example.CoM") <=> "example.com") assert_equal(false, Name.create("www.example.CoM") >= "example.com") assert_equal(false, Name.create("www.example.CoM") > "example.com") assert_equal(false, Name.create("example.CoM") < "example.com") assert_equal(true, Name.create("example.CoM") <= "example.com") assert_equal(0, Name.create("example.CoM") <=> "example.com") assert_equal(true, Name.create("example.CoM") >= "example.com") assert_equal(false, Name.create("example.CoM") > "example.com") assert_equal(false, Name.create("CoM") < "example.com") assert_equal(false, Name.create("CoM") <= "example.com") assert_equal(+1, Name.create("CoM") <=> "example.com") assert_equal(true, Name.create("CoM") >= "example.com") assert_equal(true, Name.create("CoM") > "example.com") assert_equal(nil, Name.create("bar.CoM") < "example.com") assert_equal(nil, Name.create("bar.CoM") <= "example.com") assert_equal(nil, Name.create("bar.CoM") <=> "example.com") assert_equal(nil, Name.create("bar.CoM") >= "example.com") assert_equal(nil, Name.create("bar.CoM") > "example.com") assert_equal(nil, Name.create("net.") < "com") assert_equal(nil, Name.create("net.") <= "com") assert_equal(nil, Name.create("net.") <=> "com") assert_equal(nil, Name.create("net.") >= "com") assert_equal(nil, Name.create("net.") > "com") end end