Bug #1744
closedError with Marshal dump/load on a delegated class.
Description
=begin
Instance variables are not handled when using Marshal with a delegated class.
Here is an example :
on Ruby 1.8, the instance variable @var will be copied fine.
on Ruby 1.9.1, it is set to nil.
It seems to only occur with class inherited from DelegateClass.
==================================
require 'delegate'
class C < DelegateClass(Integer)
attr_accessor :var
def initialize
@var = 1
end
end
c = C.new
p c.var # => 1
d = Marshal.load(Marshal.dump(c))
p d.var # => nil on Ruby 1.9
=end
Files
Updated by yugui (Yuki Sonoda) almost 15 years ago
- Target version set to 1.9.2
- ruby -v set to ruby 1.9.2dev (2009-11-17 trunk 25805) [i386-darwin9.8.0]
=begin
It seems a possible bug rather than a backport task. It can be reproduced in the trunk version.
=end
Updated by nobu (Nobuyoshi Nakada) almost 15 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
=begin
This issue was solved with changeset r26007.
Guillaume, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
=end
Updated by nobu (Nobuyoshi Nakada) almost 15 years ago
- Status changed from Closed to Open
=begin
=end
Updated by marcandre (Marc-Andre Lafortune) almost 15 years ago
- Status changed from Open to Closed
=begin
This issue was solved with changeset r26163.
Guillaume, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
=end
Updated by marcandre (Marc-Andre Lafortune) almost 15 years ago
- Category set to lib
=begin
Fixed also in 1.8 with r26164. This particular example worked in 1.8 because DelegateClass does not return a subclass of Delegator in 1.8, but the same bug existed for SimpleDelegator, for example.
Also added basic RubySpec for this.
=end
Updated by nobu (Nobuyoshi Nakada) almost 15 years ago
=begin
Hi,
At Thu, 24 Dec 2009 13:14:43 +0900,
Marc-Andre Lafortune wrote in [ruby-core:27306]:
Fixed also in 1.8 with r26164. This particular example worked
in 1.8 because DelegateClass does not return a subclass of
Delegator in 1.8, but the same bug existed for
SimpleDelegator, for example.Also added basic RubySpec for this.
This change has broken marshal format comatibility.
$ cat d.rb
require 'delegate'
class A < DelegateClass(Array)
end
$ ruby -v
ruby 1.9.2dev (2009-12-19 trunk 26127) [universal.x86_64-darwin9.0]
$ ./ruby -v
ruby 1.9.2dev (2009-12-23 trunk 26157) [universal.x86_64-darwin9.0]
$ ruby -I. -rd -e 'Marshal.dump(A.new([]), STDOUT)' | ./ruby -I. -rd -e 'p Marshal.load(STDIN)'
/Users/nobu/src/ruby/ruby-1.9.2/src/lib/delegate.rb:195:in marshal_load': undefined method
each_with_index' for nil:NilClass (NoMethodError)
from -e:1:in load' from -e:1:in
'
--
Nobu Nakada
=end
Updated by marcandre (Marc-Andre Lafortune) almost 15 years ago
- Status changed from Closed to Open
=begin
On Sun, Dec 27, 2009 at 8:19 PM, Nobuyoshi Nakada nobu@ruby-lang.org wrote:
This change has broken marshal format comatibility.
Indeed.
I can't think of a way to make it backward compatible, but for forward compatibility, how about the following?
diff --git a/lib/delegate.rb b/lib/delegate.rb
index f8a71f1..1516dac 100644
--- a/lib/delegate.rb
+++ b/lib/delegate.rb
@@ -184,16 +184,21 @@ class Delegator
# Serialization support for the object returned by __getobj__.
def marshal_dump
[
-
]:__v2__, instance_variables, instance_variables.map{|var| instance_variable_get(var)}, __getobj__
endReinitializes delegation from a serialized object.¶
- def marshal_load(obj)
- vars, values, obj = obj
- vars.each_with_index{|var, i| instance_variable_set(var, values[i])}
- setobj(obj)
- def marshal_load(data)
- version, vars, values, obj = data
- if version == :v2
-
vars.each_with_index{|var, i| instance_variable_set(var, values[i])}
-
__setobj__(obj)
- else
-
__setobj__(data)
- end
end
=end
Updated by marcandre (Marc-Andre Lafortune) almost 15 years ago
- Status changed from Open to Closed
=begin
This issue was solved with changeset r26195.
Guillaume, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
=end