Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subclassed Hash with overridden #initialize cannot be deserialized #196

Closed
mbklein opened this issue Jun 24, 2014 · 2 comments
Closed

Subclassed Hash with overridden #initialize cannot be deserialized #196

mbklein opened this issue Jun 24, 2014 · 2 comments

Comments

@mbklein
Copy link

mbklein commented Jun 24, 2014

#!/usr/bin/env ruby

gem 'psych', '2.0.5'
require 'psych'

class HashThing < Hash
  attr :obj
  def initialize(obj)
    @obj = obj
  end
end

a = [1,2,3,4,5]
t1 = HashThing.new(a)
t2 = Psych.load(Psych.dump(t1))
puts t2.obj

The YAML.load line raises ArgumentError: wrong number of arguments (0 for 1).

It only seems to be a problem with Hash descendants. Array and String both work as expected; I haven't bothered to test any other classes.

Tested with different combinations of the following:

  • Ruby 1.9.3 (p429 and p545), 2.0.0 (p451), 2.1.0 (p0)
  • Psych 1.2.2, 1.3.4, 2.0.5

Backtrace (from Ruby 2.1.0/Psych 2.0.5):

./psych_bug.rb:8:in `initialize': wrong number of arguments (0 for 1) (ArgumentError)
    from .../lib/ruby/gems/2.1.0/gems/psych-2.0.5/lib/psych/visitors/to_ruby.rb:263:in `new'
    from .../lib/ruby/gems/2.1.0/gems/psych-2.0.5/lib/psych/visitors/to_ruby.rb:263:in `visit_Psych_Nodes_Mapping'
    from .../lib/ruby/gems/2.1.0/gems/psych-2.0.5/lib/psych/visitors/visitor.rb:15:in `visit'
    from .../lib/ruby/gems/2.1.0/gems/psych-2.0.5/lib/psych/visitors/visitor.rb:5:in `accept'
    from .../lib/ruby/gems/2.1.0/gems/psych-2.0.5/lib/psych/visitors/to_ruby.rb:31:in `accept'
    from .../lib/ruby/gems/2.1.0/gems/psych-2.0.5/lib/psych/visitors/to_ruby.rb:278:in `visit_Psych_Nodes_Document'
    from .../lib/ruby/gems/2.1.0/gems/psych-2.0.5/lib/psych/visitors/visitor.rb:15:in `visit'
    from .../lib/ruby/gems/2.1.0/gems/psych-2.0.5/lib/psych/visitors/visitor.rb:5:in `accept'
    from .../lib/ruby/gems/2.1.0/gems/psych-2.0.5/lib/psych/visitors/to_ruby.rb:31:in `accept'
    from .../lib/ruby/gems/2.1.0/gems/psych-2.0.5/lib/psych/nodes/node.rb:37:in `to_ruby'
    from .../lib/ruby/gems/2.1.0/gems/psych-2.0.5/lib/psych.rb:246:in `load'
    from ./psych_bug.rb:15:in `<main>'
@jrafanie
Copy link
Contributor

See #43. We have a workaround that's less than ideal but it works. I'm assuming that Hash.new runs through C code and doesn't invoke your initialize in ruby land, hence you get (0 for 1). I'd recommend against subclassing Hash but if you have to, you can set instance variables and use a workaround like ours.

@tenderlove
Copy link
Member

Seems it was because I was calling new on the Hash class, rather than allocate.

headius pushed a commit to headius/psych that referenced this issue Jan 8, 2020
* master: (21 commits)
  * ext/psych/lib/psych/visitors/to_ruby.rb: call `allocate` on hash subclasses.  Fixes github.com/ruby/issues/196
  * ext/psych/lib/psych/visitors/to_ruby.rb: revive hashes with ivars
  removed isolate task
  removed isolate plugin
  added minitest dependency into gemspec
  added install task into travis
  added ruby-head env
  bumping version to 2.0.8
  fixed build error caused by trunk changes
  bumping version to 2.0.7
  merging from ruby trunk
  backport r48512 from ruby/ruby trunk.
  Add changelog for 2a4d956
  backport r48214 from ruby/ruby trunk.
  Allow dumping any BasicObject that defines #marshal_dump or #marshal_load
  bumping version
  * ext/psych/lib/psych/visitors/yaml_tree.rb: fix NameError dumping and   loading. Fixes GH ruby#85. Thanks @brentdax for the patch! * test/psych/test_exception.rb: test for fix
  * ext/psych/lib/psych/scalar_scanner.rb: fix loading strings that   look like integers but have a newline. Fixes GH ruby#189 * test/psych/test_string.rb: test for fix
  * ext/psych/lib/psych/visitors/to_ruby.rb: merge keys with a hash   should merge the hash in to the parent. * test/psych/test_merge_keys.rb: test for change. Fixes GH ruby#202
  * ext/psych/lib/psych/visitors/to_ruby.rb: quoted "<<" strings   should not be treated as merge keys. * ext/psych/lib/psych/visitors/yaml_tree.rb: hashes with keys   containing "<<" should roundtrip. * test/psych/test_merge_keys.rb: test for change. Fixes GH ruby#203
  ...

Conflicts:
	lib/psych/visitors/yaml_tree.rb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants