[#24536] 「Rubyの落し方」 v.s. ruby_1_8 — akira yamada / やまだあきら <akira@...>

<URL:http://jp.rubyist.net/magazine/?0002-RubyCore>

40 messages 2004/10/20
[#24541] Re: 「Rubyの落し方」 v.s. ruby_1_8 — Yukihiro Matsumoto <matz@...> 2004/10/20

まつもと ゆきひろです

[#24599] 1.8.2 preview3? — akira yamada / やまだあきら <akira@...> 2004/10/26

2004-10-20 (水) の 21:38 +0900 に Yukihiro Matsumoto さんは書きました:

[#24605] Re: 1.8.2 preview3? — akira yamada / やまだあきら <akira@...> 2004/10/27

2004-10-26 (火) の 16:16 +0900 に akira yamada / やまだあきら さんは書きました:

[#24606] Re: 1.8.2 preview3? — Yukihiro Matsumoto <matz@...> 2004/10/27

まつもと ゆきひろです

[#24608] Re: 1.8.2 preview3? — akira yamada / やまだあきら <akira@...> 2004/10/27

2004-10-27 (水) の 11:48 +0900 に Yukihiro Matsumoto さんは書きました:

[#24620] Re: 1.8.2 preview3? — akira yamada / やまだあきら <akira@...> 2004/10/27

2004-10-27 (水) の 12:42 +0900 に akira yamada / やまだあきら さんは書きました:

[#24629] Re: 1.8.2 preview3? — Tanaka Akira <akr@...17n.org> 2004/10/29

In article <1098888819.9446.14.camel@rice.p.arika.org>,

[ruby-dev:24625] OpenStruct can't be dumped

From: nobu@...
Date: 2004-10-28 05:12:20 UTC
List: ruby-dev #24625
なかだです。

OpenStructがMarshal.dumpできなくなっています。

  $ ruby -v -rostruct -e 'x=OpenStruct.new;x.foo=1;Marshal.dump(x)'
  ruby 1.9.0 (2004-10-27) [i686-linux]
  -e:1:in `dump': singleton can't be dumped (TypeError)
          from -e:1

また、newのときに初期化されたものに関しては、[ruby-talk:117889]
は直っていないようです。

  $ ruby -rostruct -e 'def foo;"method";end;p OpenStruct.new(:foo=>1).send(:foo)'
  "method"

marshal_dumpでは互換性がなくなってしまうのが問題ですが。


Index: lib/ostruct.rb
===================================================================
RCS file: /cvs/ruby/src/ruby/lib/ostruct.rb,v
retrieving revision 1.12
diff -U2 -p -d -r1.12 ostruct.rb
--- lib/ostruct.rb	27 Oct 2004 09:29:24 -0000	1.12
+++ lib/ostruct.rb	28 Oct 2004 05:10:23 -0000
@@ -48,5 +48,6 @@ class OpenStruct
     if hash
       for k,v in hash
-	@table[k.to_sym] = v
+	@table[k = k.to_sym] = v
+        new_ostruct_member(k)
       end
     end
@@ -56,12 +57,29 @@ class OpenStruct
   def initialize_copy(orig)
     super
+    @table.each_key {|k| remove_ostruct_member(k)}
     @table = @table.dup
+    @table.each_key {|k| new_ostruct_member(k)}
+  end
+
+  def marshal_dump
+    @table
+  end
+
+  def marshal_load(x)
+    @table = x
   end
 
   def new_ostruct_member(name)
-    self.instance_eval %{
-      def #{name}; @table[:#{name}]; end
-      def #{name}=(x); @table[:#{name}] = x; end
-    }
+    class << self; self; end.class_eval do
+      define_method(name) do || @table[name]; end
+      define_method("#{name}=") do |x| @table[name] = x; end
+    end
+  end
+
+  def remove_ostruct_member(name)
+    class << self; self; end.class_eval do
+      remove_method(name)
+      remove_method("#{name}=")
+    end
   end
 
@@ -77,5 +95,6 @@ class OpenStruct
       end
       mname.chop!
-      @table[mname.intern] = args[0]
+      mname = mname.intern
+      @table[mname] = args[0]
       self.new_ostruct_member(mname)
     elsif len == 0
@@ -90,5 +109,7 @@ class OpenStruct
   #
   def delete_field(name)
-    @table.delete name.to_sym
+    name = name.to_sym
+    remove_ostruct_member(name)
+    @table.delete(name)
   end
 


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread

Prev Next