Project

General

Profile

Actions

Feature #1905

closed

How about IPAddr#<=> to take care of mask_addr?

Added by no6v (Nobuhiro IMAI) over 14 years ago. Updated about 12 years ago.

Status:
Rejected
Target version:
[ruby-dev:39038]

Description

=begin
いまいです。

#1877 はありがとうございました。

IPAddr のインスタンスがハッシュのキーに出来るようになったので、簡単な
Access Control List を書いてみたのですが、

RUBY_DESCRIPTION
=> "ruby 1.9.2dev (2009-08-07 trunk 24440) [i686-linux]"
acl = {
?> IPAddr.new("192.168.2.0/29") => :admin,
?> IPAddr.new("192.168.2.0/24") => :user,
?> }
=> {#<IPAddr: IPv4:192.168.2.0/255.255.255.248>=>:admin, #<IPAddr: IPv4:192.168.2.0/255.255.255.0>=>:user}
acl.select{|r, | r === "192.168.2.56"}.max.last
=> :user
acl.select{|r, | r === "192.168.2.1"}.max.last
=> :user

と、ちょっと残念な感じです。<=> で、@addr が同じ場合は @mask_addr の大
きい方が IPAddr として大きいとすると、ネットマスクの長い方が採用される
ようなイメージでうれしい気がするのですが、どうでしょうか?

また、これで(というか元から?) IPAddr#== は不要な気がするのですが、何
か見落としてるでしょうか?

IPAddr.new("192.168.2.0/24") == IPAddr.new("192.168.2.0/32")

が true から false に変わるという仕様変更なのですが、どうでしょうか?

Nobuhiro IMAI
Key fingerprint = F39E D552 545D 7C64 D690 F644 5A15 746C BD8E 7106

Index: lib/ipaddr.rb

--- lib/ipaddr.rb (revision 24440)
+++ lib/ipaddr.rb (working copy)
@@ -133,16 +133,10 @@ class IPAddr
# Returns a new ipaddr built by bitwise negation.
def ~
return self.clone.set(addr_mask(~@addr))
end

  • Returns true if two ipaddrs are equal.

  • def ==(other)

  • other = coerce_other(other)

  • return @family == other.family && @addr == other.to_i

  • end

  • Returns a new ipaddr built by masking IP address with the given

    prefixlen/netmask. (e.g. 8, 64, "255.255.255.0", etc.)

    def mask(prefixlen)
    return self.clone.mask!(prefixlen)
    end
    @@ -325,11 +319,11 @@ class IPAddr
    def <=>(other)
    other = coerce_other(other)

    return nil if other.family != @family

  • return @addr <=> other.to_i

  • return [@addr, @mask_addr] <=> [other.to_i, other.mask_addr]
    end
    include Comparable
# Checks equality used by Hash.
def eql?(other)

@@ -372,10 +366,12 @@ class IPAddr
af, _to_string(@addr), _to_string(@mask_addr))
end

protected
  • attr_reader :mask_addr
  • def set(addr, *family)
    case family[0] ? family[0] : @family
    when Socket::AF_INET
    if addr < 0 || addr > IN4MASK
    raise ArgumentError, "invalid address"
    @@ -789,15 +785,24 @@ class TC_Operator < Test::Unit::TestCase
    a = ~@in6_addr_any
    assert_equal(IN6MASK128, a.to_s)
    assert_equal("::", @in6_addr_any.to_s)
    end
  • def test_equal
  • assert_equal(true, @A (A A) == IPAddr.new("3ffe:505:2::"))
  • def test_compare
  • assert_equal(true, @A (A A) == IPAddr.new("3ffe:505:2::/48"))
  • assert_equal(false, @A (A A) == IPAddr.new("3ffe:505:2::"))
    assert_equal(false, @A (A A) == IPAddr.new("3ffe:505:3::"))
    assert_equal(true, @A (A A) != IPAddr.new("3ffe:505:3::"))
  • assert_equal(false, @A (A A) != IPAddr.new("3ffe:505:2::"))
  • assert_equal(false, @A (A A) != IPAddr.new("3ffe:505:2::/48"))
  • x = IPAddr.new("3ffe:505:3::/48")
  • y = IPAddr.new("3ffe:505:2::/64")
  • assert_equal(true, @A (A A) < x)
  • assert_equal(true, @A (A A) < y)
  • assert_equal(false, x < y)
  • min, max = [y, x, @A (A A)].minmax
  • assert_equal(@A (A A), min)
  • assert_equal(x, max)
    end
def test_mask
  a = @a.mask(32)
  assert_equal("3ffe:505::", a.to_s)

=end


Related issues 1 (0 open1 closed)

Related to Ruby master - Feature #1275: IPAddr unnecessarily destroys information on creationRejectedknu (Akinori MUSHA)03/12/2009Actions
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0