[前][次][番号順一覧][スレッド一覧]

ruby-changes:2136

From: ko1@a...
Date: 5 Oct 2007 03:23:51 +0900
Subject: [ruby-changes:2136] knu - Ruby:r13627 (trunk): * lib/ipaddr.rb (coerce_other): Support type coercion and make &,

knu	2007-10-05 03:23:22 +0900 (Fri, 05 Oct 2007)

  New Revision: 13627

  Modified files:
    trunk/ChangeLog
    trunk/lib/ipaddr.rb

  Log:
    * lib/ipaddr.rb (coerce_other): Support type coercion and make &,
      |, == and include? accept a string or an integer instead of an
      IPAddr object as the argument.
    
    * lib/ipaddr.rb (initialize): Give better error messages.
    
    * lib/ipaddr.rb: Improve documentation.


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/lib/ipaddr.rb?r1=13627&r2=13626
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=13627&r2=13626

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 13626)
+++ ChangeLog	(revision 13627)
@@ -1,3 +1,13 @@
+Fri Oct  5 03:14:45 2007  Akinori MUSHA  <knu@i...>
+
+	* lib/ipaddr.rb (coerce_other): Support type coercion and make &,
+	  |, == and include? accept a string or an integer instead of an
+	  IPAddr object as the argument.
+
+	* lib/ipaddr.rb (initialize): Give better error messages.
+
+	* lib/ipaddr.rb: Improve documentation.
+
 Thu Oct  4 20:45:53 2007  NAKAMURA Usaku  <usa@r...>
 
 	* process.c (Init_process): win32 has our own WNOHANG definition, so
Index: lib/ipaddr.rb
===================================================================
--- lib/ipaddr.rb	(revision 13626)
+++ lib/ipaddr.rb	(revision 13627)
@@ -2,6 +2,7 @@
 # ipaddr.rb - A class to manipulate an IP address
 #
 # Copyright (c) 2002 Hajimu UMEMOTO <ume@m...>.
+# Copyright (c) 2007 Akinori MUSHA <knu@i...>.
 # All rights reserved.
 #
 # You can redistribute and/or modify it under the same terms as Ruby.
@@ -107,12 +108,12 @@
 
   # 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(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(other).to_i)
   end
 
   # Returns a new ipaddr built by bitwise right-shift.
@@ -130,12 +131,10 @@
     return self.clone.set(addr_mask(~@addr))
   end
 
-  # Returns true if two ipaddr are equal.
+  # Returns true if two ipaddrs are equal.
   def ==(other)
-    if other.kind_of?(IPAddr) && @family != other.family
-      return false
-    end
-    return (@addr == other.to_i)
+    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
@@ -149,10 +148,12 @@
   # e.g.:
   #   require 'ipaddr'
   #   net1 = IPAddr.new("192.168.2.0/24")
-  #   p net1.include?(IPAddr.new("192.168.2.0"))	#=> true
-  #   p net1.include?(IPAddr.new("192.168.2.255"))	#=> true
-  #   p net1.include?(IPAddr.new("192.168.3.0"))	#=> false
+  #   net2 = IPAddr.new("192.168.2.100")
+  #   net3 = IPAddr.new("192.168.3.0")
+  #   p net1.include?(net2)	#=> true
+  #   p net1.include?(net3)	#=> false
   def include?(other)
+    other = coerce_other(other)
     if ipv4_mapped?
       if (@mask_addr >> 32) != 0xffffffffffffffffffffffff
 	return false
@@ -165,17 +166,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
@@ -391,22 +387,36 @@
 
   private
 
-  # Creates a new ipaddr containing the given human readable form of
-  # an IP address.  It also accepts `address/prefixlen' and
-  # `address/mask'.  When prefixlen or mask is specified, it returns a
-  # masked ipaddr.  IPv6 address may beenclosed with `[' and `]'.
+  # Creates a new ipaddr object either from a human readable IP
+  # address representation in string, or from a packed in_addr value
+  # followed by an address family.
+  # 
+  # In the former case, the following are the valid formats that will
+  # be recognized: "address", "address/prefixlen" and "address/mask",
+  # where IPv6 address may be enclosed in square brackets (`[' and
+  # `]').  If a prefixlen or a mask is specified, it returns a masked
+  # IP address.  Although the address family is determined
+  # automatically from a specified string, you can specify one
+  # explicitly by the optional second argument.
+  # 
+  # Otherwise an IP addess is generated from a packed in_addr value
+  # and an address family.
   #
-  # Although an address family is determined automatically from a
-  # specified address, you can specify an address family explicitly by
-  # the optional second argument.
+  # The IPAddr class defines many methods and operators, and some of
+  # those, such as &, |, include? and ==, accept a string, or a packed
+  # in_addr value instead of an IPAddr object.
   def initialize(addr = '::', family = Socket::AF_UNSPEC)
     if !addr.kind_of?(String)
-      if family != Socket::AF_INET6 && family != Socket::AF_INET
-	raise ArgumentError, "unsupported address family"
+      case family
+      when Socket::AF_INET, Socket::AF_INET6
+        set(addr.to_i, family)
+        @mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
+        return
+      when Socket::AF_UNSPEC
+	raise ArgumentError, "address family must be specified"
+      else
+	raise ArgumentError, "unsupported address family: #{family}"
       end
-      set(addr, family)
-      @mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
-      return
     end
     prefix, prefixlen = addr.split('/')
     if prefix =~ /^\[(.*)\]$/i
@@ -433,7 +443,7 @@
       @family = Socket::AF_INET6
     end
     if family != Socket::AF_UNSPEC && @family != family
-      raise ArgumentError, "address family unmatch"
+      raise ArgumentError, "address family mismatch"
     end
     if prefixlen
       mask!(prefixlen)
@@ -442,6 +452,17 @@
     end
   end
 
+  def coerce_other(other)
+    case other
+    when IPAddr
+      other
+    when String
+      self.class.new(other)
+    else
+      self.class.new(other, @family)
+    end
+  end
+
   def in_addr(addr)
     if addr =~ /^\d+\.\d+\.\d+\.\d+$/
       n = 0

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧]