json icon indicating copy to clipboard operation
json copied to clipboard

Getting `TypeError: wrong argument type JSON::Pure::Generator::State (expected Data)` from json/pure when dumping a hash after loading json/ext

Open myronmarston opened this issue 12 years ago • 2 comments

Given json_pure_bug.rb:

require 'json/ext'
require 'json/pure'

hash = { "a" => 7, "nested" => { "hash" => [1, 2, 3] }}
JSON.dump(hash)

When I run it:

➜ ruby --version
ruby 1.9.3p448 (2013-06-27 revision 41675) [x86_64-darwin12.4.0]
➜ ruby json_pure_bug.rb
/Users/myron/code/vcr/bundle/ruby/1.9.1/gems/json-1.8.0/lib/json/pure/generator.rb:366:in `to_json': wrong argument type JSON::Pure::Generator::State (expected Data) (TypeError)
    from /Users/myron/code/vcr/bundle/ruby/1.9.1/gems/json-1.8.0/lib/json/pure/generator.rb:366:in `block in json_transform'
    from /Users/myron/code/vcr/bundle/ruby/1.9.1/gems/json-1.8.0/lib/json/pure/generator.rb:359:in `each'
    from /Users/myron/code/vcr/bundle/ruby/1.9.1/gems/json-1.8.0/lib/json/pure/generator.rb:359:in `json_transform'
    from /Users/myron/code/vcr/bundle/ruby/1.9.1/gems/json-1.8.0/lib/json/pure/generator.rb:341:in `to_json'
    from /Users/myron/code/vcr/bundle/ruby/1.9.1/gems/json-1.8.0/lib/json/pure/generator.rb:293:in `generate'
    from /Users/myron/code/vcr/bundle/ruby/1.9.1/gems/json-1.8.0/lib/json/common.rb:223:in `generate'
    from /Users/myron/code/vcr/bundle/ruby/1.9.1/gems/json-1.8.0/lib/json/common.rb:394:in `dump'
    from json_pure_bug.rb:5:in `<main>'

Note that when I comment out the json/ext require, the problem goes away.

Obviously, it's not recommended to load both json/ext and json/pure; however, for VCR's test suite, as part of testing its multi_json integration, I iterate through a set of multi_json's adapters (including both :json_gem and :json_pure), set MultiJson.engine to it, and run a test against that adapter. As a result, json/ext and json/pure both get loaded in the same process, and this error occurs.

myronmarston avatar Sep 23 '13 04:09 myronmarston

Unfortunately in Ruby Mixins cannot be unincluded, so I cannot avoid this error. Maybe using refinements can be used as an alternative approach. I remember trying this once, but there were still some problems I encountered.

flori avatar Sep 23 '13 15:09 flori

It works if you reverse the require order, though:

require 'json/pure'
require 'json/ext'

hash = { "a" => 7, "nested" => { "hash" => [1, 2, 3] }}
JSON.dump(hash)

Also, I totally understand about this not being a use case you want to support. That's fine. But maybe your library could detect that json/ext has been loaded, and, if so, make json/pure be a no-op that prints a warning like:

WARNING: Ignoring require of `json/pure` since `json/ext` has already been successfully loaded and both cannot be active at the same time.

myronmarston avatar Sep 23 '13 20:09 myronmarston