From: Akinori MUSHA Date: 2007-10-02T20:17:14+09:00 Subject: [ruby-dev:31925] Re: ipaddr --pgp-sign-Multipart_Tue_Oct__2_20:17:15_2007-1 Content-Type: text/plain; charset=ISO-2022-JP At Sun, 30 Sep 2007 00:27:59 +0900, Kazuhiro NISHIYAMA wrote: > 西山和広です。 > > ipaddrで > IPAddr.new("127.0.0.0/8").include?("127.0.0.1") > がfalseになって悩んだことがあるので、文字列も自動で変換して > うけつけてくれると嬉しいのではないかと思います。 > > # 今は > # IPAddr.new("127.0.0.0/8").include?(IPAddr.new("127.0.0.1")) > # じゃないとだめ。  こうするといいかな。 Index: ipaddr.rb =================================================================== --- ipaddr.rb (revision 13588) +++ ipaddr.rb (working copy) @@ -105,14 +105,26 @@ return s end + def coerce(other) + case other + when IPAddr + other + when String + self.class.new(other) + else + self.class.new(other, @family) + end + end + private coerce + # Returns a new ipaddr built by bitwise AND. def &(other) - return self.clone.set(@addr & other.to_i) + return self.clone.set(@addr & coerce(other).to_i) end # Returns a new ipaddr built by bitwise OR. def |(other) - return self.clone.set(@addr | other.to_i) + return self.clone.set(@addr | coerce(other).to_i) end # Returns a new ipaddr built by bitwise right-shift. @@ -132,10 +144,7 @@ # Returns true if two ipaddr are equal. def ==(other) - if other.kind_of?(IPAddr) && @family != other.family - return false - end - return (@addr == other.to_i) + return @family == other.family && @addr == coerce(other).to_i end # Returns a new ipaddr built by masking IP address with the given @@ -153,6 +162,7 @@ # p net1.include?(IPAddr.new("192.168.2.255")) #=> true # p net1.include?(IPAddr.new("192.168.3.0")) #=> false def include?(other) + other = coerce(other) if ipv4_mapped? if (@mask_addr >> 32) != 0xffffffffffffffffffffffff return false @@ -165,17 +175,12 @@ addr = @addr family = @family end - if other.kind_of?(IPAddr) - if other.ipv4_mapped? - other_addr = (other.to_i & IN4MASK) - other_family = Socket::AF_INET - else - other_addr = other.to_i - other_family = other.family - end - else # Not IPAddr - assume integer in same family as us - other_addr = other.to_i - other_family = family + if other.ipv4_mapped? + other_addr = (other.to_i & IN4MASK) + other_family = Socket::AF_INET + else + other_addr = other.to_i + other_family = other.family end if family != other_family  ついでに <=> と succ を定義して Comparable にすると、 Range を 作ったりできますね。 > # ライブラリのメンテナの話で思いだした。  梅本さんにCCしておきます。 -- / /__ __ Akinori.org / MUSHA.org / ) ) ) ) / FreeBSD.org / Ruby-lang.org Akinori MUSHA aka / (_ / ( (__( @ iDaemons.org / and.or.jp "Different eyes see different things, Different hearts beat on different strings -- But there are times for you and me when all such things agree" --pgp-sign-Multipart_Tue_Oct__2_20:17:15_2007-1 Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (FreeBSD) iD8DBQBHAii7kgvvx5/Z4e4RAh/aAKC2Ec4PKNrZ+BL0xHFycsgTquIrRACfbvNE 5UvSGn/L6hjh6/Cnuoku8K4= =gZWH -----END PGP SIGNATURE----- --pgp-sign-Multipart_Tue_Oct__2_20:17:15_2007-1--