[#38392] Enumerable#gather_each — Tanaka Akira <akr@...>

ときに、複数行をまとめて扱いたいことがあります。

47 messages 2009/05/09
[#38394] Re: Enumerable#gather_each — ujihisa <ujihisa@...> 2009/05/09

ujihisaと申します。

[#38400] Re: Enumerable#gather_each — Yukihiro Matsumoto <matz@...> 2009/05/09

まつもと ゆきひろです

[#38399] Re: Enumerable#gather_each — "Akinori MUSHA" <knu@...> 2009/05/09

At Sat, 9 May 2009 15:30:20 +0900,

[#38405] Re: Enumerable#gather_each — Tanaka Akira <akr@...> 2009/05/10

In article <86r5yy2nrg.knu@iDaemons.org>,

[#38417] Re: Enumerable#gather_each — "Akinori MUSHA" <knu@...> 2009/05/10

At Sun, 10 May 2009 10:08:47 +0900,

[#38524] [Bug #1503] -Kuをつけた時、/[#{s}]/n と Regexp.new("[#{s}]",nil,"n") で実行結果が異なる — sinnichi eguchi <redmine@...>

Bug #1503: -Kuをつけた時、/[#{s}]/n と Regexp.new("[#{s}]",nil,"n") で実行結果が異なる

8 messages 2009/05/22

[ruby-dev:38377] Marshaling URI between 1.8 and 1.9

From: Tanaka Akira <akr@...>
Date: 2009-05-06 05:21:34 UTC
List: ruby-dev #38377
気がついたんですが、URI オブジェクトを marshal で 1.9 から
1.8 に移そうとすると失敗します。

% ruby -v    
ruby 1.9.2dev (2009-05-02 trunk 23326) [i686-linux]
% ruby-1.8 -v                                                          
ruby 1.8.8dev (2009-04-22 revision 23257) [i686-linux]

% ruby -ruri -e 'Marshal.dump(URI("http://example.org"), STDOUT)' > u19
% ruby-1.8 -ruri -e 'Marshal.load(STDIN)' < u19
-e:1:in `load': undefined class/module URI::Parser (ArgumentError)
        from -e:1

理由はエラーメッセージに書いてある通りで、1.9 の URI オブジェ
クトには URI::Parser オブジェクトが入っているのに、1.8 には
URI::Parser クラスがないからです。

逆に、1.8 の URI オブジェクトを 1.9 に移すのは、Mashal.load
までは動きます。

% ruby-1.8 -ruri -e 'Marshal.dump(URI("http://example.org"), STDOUT)' > u18
% ruby -ruri -e 'p Marshal.load(STDIN)' < u18
#<URI::HTTP:0xa072150 URL:http://example.org>

でも、それになにか連結したりするとエラーになります。

% ruby -v -ruri -e 'p Marshal.load(STDIN) + "foo"' < u18
ruby 1.9.2dev (2009-05-02 trunk 23326) [i686-linux]
/home/akr/ruby/yarvo0/lib/ruby/1.9.1/uri/generic.rb:780: warning: instance variable @parser not initialized
/home/akr/ruby/yarvo0/lib/ruby/1.9.1/uri/generic.rb:737:in `rescue in merge': undefined method `parse' for nil:NilClass (NoMethodError)
        from /home/akr/ruby/yarvo0/lib/ruby/1.9.1/uri/generic.rb:734:in `merge'
        from -e:1:in `<main>'

この理由は @parser がないからです。

このパーザの有無は、marshal した結果のサイズにも影響してい
て、1.9 では 20K ほど大きくなっています。

% ls -l u18 u19
-rw-r--r-- 1 akr akr   131 2009-05-06 14:08 u18
-rw-r--r-- 1 akr akr 21333 2009-05-06 14:08 u19

思うのですが、デフォルトのパーザを使うときはインスタンス変数
には記録しないようにするのはどうでしょうか。

そうすれば、(デフォルトのパーザを使用する URI では) パーザが
marshal したデータに表れなくなるので、1.8 と 1.9 の間で
marshal できるようになります。

% svn diff --diff-cmd diff -x '-u -p'
Index: lib/uri/mailto.rb
===================================================================
--- lib/uri/mailto.rb	(revision 23350)
+++ lib/uri/mailto.rb	(working copy)
@@ -159,7 +159,7 @@ module URI
       return true unless v
       return true if v.size == 0
 
-      if @parser.regexp[:OPAQUE] !~ v || /\A#{MAILBOX_PATTERN}*\z/o !~ v
+      if parser.regexp[:OPAQUE] !~ v || /\A#{MAILBOX_PATTERN}*\z/o !~ v
         raise InvalidComponentError,
           "bad component(expected opaque component): #{v}"
       end
@@ -183,7 +183,7 @@ module URI
       return true unless v
       return true if v.size == 0
 
-      if @parser.regexp[:OPAQUE] !~ v ||
+      if parser.regexp[:OPAQUE] !~ v ||
           /\A(#{HEADER_PATTERN}(?:\&#{HEADER_PATTERN})*)\z/o !~ v
         raise InvalidComponentError,
           "bad component(expected opaque component): #{v}"
@@ -239,18 +239,18 @@ module URI
     #   # => "To: ruby-list@ruby-lang.org\nSubject: subscribe\nCc: myaddr\n\n\n"
     #
     def to_mailtext
-      to = @parser.unescape(@to)
+      to = parser.unescape(@to)
       head = ''
       body = ''
       @headers.each do |x|
         case x[0]
         when 'body'
-          body = @parser.unescape(x[1])
+          body = parser.unescape(x[1])
         when 'to'
-          to << ', ' + @parser.unescape(x[1])
+          to << ', ' + parser.unescape(x[1])
         else
-          head << @parser.unescape(x[0]).capitalize + ': ' +
-            @parser.unescape(x[1])  + "\n"
+          head << parser.unescape(x[0]).capitalize + ': ' +
+            parser.unescape(x[1])  + "\n"
         end
       end
 
Index: lib/uri/generic.rb
===================================================================
--- lib/uri/generic.rb	(revision 23350)
+++ lib/uri/generic.rb	(working copy)
@@ -73,7 +73,7 @@ module URI
         if args.kind_of?(Array)
           return self.build(args.collect{|x|
             if x
-              @parser.escape(x)
+              parser.escape(x)
             else
               x
             end
@@ -82,7 +82,7 @@ module URI
           tmp = {}
           args.each do |key, value|
             tmp[key] = if value
-                @parser.escape(value)
+                parser.escape(value)
               else
                 value
               end
@@ -121,7 +121,7 @@ module URI
         "expected Array of or Hash of components of #{self.class} (#{self.class.component.join(', ')})"
       end
 
-      tmp << DEFAULT_PARSER
+      tmp << nil
       tmp << true
       return self.new(*tmp)
     end
@@ -172,7 +172,7 @@ module URI
       @opaque = nil
       @registry = nil
       @fragment = nil
-      @parser = parser
+      @parser = parser == DEFAULT_PARSER ? nil : parser
 
       if arg_check
         self.scheme = scheme
@@ -212,7 +212,14 @@ module URI
     attr_reader :query
     attr_reader :opaque
     attr_reader :fragment
-    attr_reader :parser
+
+    def parser
+      if !defined?(@parser) || !@parser
+        DEFAULT_PARSER
+      else
+        @parser || DEFAULT_PARSER
+      end
+    end
 
     # replace self by other URI object
     def replace!(oth)
@@ -231,7 +238,7 @@ module URI
     end
 
     def check_scheme(v)
-      if v && @parser.regexp[:SCHEME] !~ v
+      if v && parser.regexp[:SCHEME] !~ v
         raise InvalidComponentError,
           "bad component(expected scheme component): #{v}"
       end
@@ -270,7 +277,7 @@ module URI
 
       return v unless v
 
-      if @parser.regexp[:USERINFO] !~ v
+      if parser.regexp[:USERINFO] !~ v
         raise InvalidComponentError,
           "bad component(expected userinfo component or user component): #{v}"
       end
@@ -291,7 +298,7 @@ module URI
           "password component depends user component"
       end
 
-      if @parser.regexp[:USERINFO] !~ v
+      if parser.regexp[:USERINFO] !~ v
         raise InvalidComponentError,
           "bad component(expected user component): #{v}"
       end
@@ -356,7 +363,7 @@ module URI
     private :split_userinfo
 
     def escape_userpass(v)
-      v = @parser.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/
+      v = parser.escape(v, /[@:\/]/o) # RFC 1738 section 3.1 #/
     end
     private :escape_userpass
 
@@ -384,7 +391,7 @@ module URI
       if @registry || @opaque
         raise InvalidURIError,
           "can not set host with registry or opaque"
-      elsif @parser.regexp[:HOST] !~ v
+      elsif parser.regexp[:HOST] !~ v
         raise InvalidComponentError,
           "bad component(expected host component): #{v}"
       end
@@ -410,7 +417,7 @@ module URI
       if @registry || @opaque
         raise InvalidURIError,
           "can not set port with registry or opaque"
-      elsif !v.kind_of?(Fixnum) && @parser.regexp[:PORT] !~ v
+      elsif !v.kind_of?(Fixnum) && parser.regexp[:PORT] !~ v
         raise InvalidComponentError,
           "bad component(expected port component): #{v}"
       end
@@ -446,7 +453,7 @@ module URI
       if @host || @port || @user # userinfo = @user + ':' + @password
         raise InvalidURIError,
           "can not set registry with host, port, or userinfo"
-      elsif v && @parser.regexp[:REGISTRY] !~ v
+      elsif v && parser.regexp[:REGISTRY] !~ v
         raise InvalidComponentError,
           "bad component(expected registry component): #{v}"
       end
@@ -476,12 +483,12 @@ module URI
       end
 
       if @scheme
-        if v && v != '' && @parser.regexp[:ABS_PATH] !~ v
+        if v && v != '' && parser.regexp[:ABS_PATH] !~ v
           raise InvalidComponentError,
             "bad component(expected absolute path component): #{v}"
         end
       else
-        if v && v != '' && @parser.regexp[:ABS_PATH] !~ v && @parser.regexp[:REL_PATH] !~ v
+        if v && v != '' && parser.regexp[:ABS_PATH] !~ v && parser.regexp[:REL_PATH] !~ v
           raise InvalidComponentError,
             "bad component(expected relative path component): #{v}"
         end
@@ -513,7 +520,7 @@ module URI
           "query conflicts with opaque"
       end
 
-      if v && v != '' && @parser.regexp[:QUERY] !~ v
+      if v && v != '' && parser.regexp[:QUERY] !~ v
           raise InvalidComponentError,
             "bad component(expected query component): #{v}"
       end
@@ -542,7 +549,7 @@ module URI
       if @host || @port || @user || @path  # userinfo = @user + ':' + @password
         raise InvalidURIError,
           "can not set opaque with host, port, userinfo or path"
-      elsif v && @parser.regexp[:OPAQUE] !~ v
+      elsif v && parser.regexp[:OPAQUE] !~ v
         raise InvalidComponentError,
           "bad component(expected opaque component): #{v}"
       end
@@ -565,7 +572,7 @@ module URI
     def check_fragment(v)
       return v unless v
 
-      if v && v != '' && @parser.regexp[:FRAGMENT] !~ v
+      if v && v != '' && parser.regexp[:FRAGMENT] !~ v
         raise InvalidComponentError,
           "bad component(expected fragment component): #{v}"
       end
@@ -777,7 +784,7 @@ module URI
       case oth
       when Generic
       when String
-        oth = @parser.parse(oth)
+        oth = parser.parse(oth)
       else
         raise ArgumentError,
           "bad argument(expected URI object or URI string)"
@@ -848,7 +855,7 @@ module URI
       case oth
       when Generic
       when String
-        oth = @parser.parse(oth)
+        oth = parser.parse(oth)
       else
         raise ArgumentError,
           "bad argument(expected URI object or URI string)"
@@ -869,7 +876,7 @@ module URI
       rel = URI::Generic.new(nil, # it is relative URI
                              self.userinfo, self.host, self.port,
                              self.registry, self.path, self.opaque,
-                             self.query, self.fragment, @parser)
+                             self.query, self.fragment, parser)
 
       if rel.userinfo != oth.userinfo ||
           rel.host.to_s.downcase != oth.host.to_s.downcase ||
@@ -960,7 +967,7 @@ module URI
       case oth
       when Generic
       when String
-        oth = @parser.parse(oth)
+        oth = parser.parse(oth)
       else
         raise ArgumentError,
           "bad argument(expected URI object or URI string)"
@@ -1059,7 +1066,7 @@ module URI
     end
 
     def eql?(oth)
-      @parser == oth.parser &&
+      parser == oth.parser &&
       self.component_ary.eql?(oth.component_ary)
     end
 
@@ -1117,7 +1124,7 @@ module URI
     def coerce(oth)
       case oth
       when String
-        oth = @parser.parse(oth)
+        oth = parser.parse(oth)
       else
         super
       end
-- 
[田中 哲][たなか あきら][Tanaka Akira]

In This Thread

Prev Next