Closed ckoch-ncsa closed 9 years ago
OpenStruct.new(nil).foo # => nil
RecursiveOpenStruct.new(nil).foo # => NoMethodError: undefined method `[]' for nil:NilClass
0.6 reworked the internals of the ROS class a bit in order to add recursion support to subscript notation and to make it possible to choose whether the input hash is mutated or duplicated, so I'm not too surprised that un-spec'd OpenStruct functionality broke. This should be an easy fix though.
@ckoch-ncsa could you look over my commit and see if that solves your problem? If so, I will cut a patch release in the next day or so.
Looks great and works as expected now. Thanks for fixing this so quickly.
Just released v0.6.5 to rubygems.
When testing RecursiveOpenStruct (ROS) using RSpec in a Rails project, my test against initializing ROS with nil is failing and reports a 'no method error for nil class' when sending a key to the ROS instance.
I am wrapping calls to RecursiveOpenStruct in a method that makes the call: RecursiveOpenStruct.new(hash, recurse_over_arrays: true)
I tested this with 2 different versions of RecursiveOpenStruct and received 2 different outcomes: first using the current 0.6.4 version gem build, I instantiated the RecursiveOpenStruct class passing nil and recurse_over_arrays: true.
RecursiveOpenStruct.new(nil, recurse_over_arrays: true)
This test failsUsing the older version 0.5.0 of the gem and the same initialization, I have no issues with the tests failing.
When I pry the session in the failing test, I see that
RecursiveOpenStruct.new(nil, recurse_over_arrays: true)
returns a RecursiveOpenStruct instance, however when I send a key to the ROS instance that does not exist, then the "NoMethodError: undefined method []' for nil:NilClass" appears.Pry session debug output: [1] pry(#RSpec::ExampleGroups::ResponseDeserializer)> described_class.recursive_open_struct(nil).client_id NoMethodError: undefined method []' for nil:NilClass from .../.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/ostruct.rb:185:in method_missing'
It appears that somewhere in the method_missing calls, the ROS object gets lost, perhaps because the instance does not correctly maintain the @table object?
Files and additional test output are below.
Test Error: `From: ../spec/lib/serializers/response_deserializer_spec.rb @ line 79 :
`
[1] pry(#RSpec::ExampleGroups::ResponseDeserializer)> nil_ostruct => #RecursiveOpenStruct:0x3fc71154d338
[2] pry(#RSpec::ExampleGroups::ResponseDeserializer)> nil_ostruct.client NoMethodError: undefined method []' for nil:NilClass from .../.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/ostruct.rb:185:in method_missing'
More console output, notice that it is not possible to assign a new key-value pair to the ROS instance that was initialized with nil.
[10] pry(main)> b=RecursiveOpenStruct.new(nil) => #RecursiveOpenStruct:0x3ff34cd4f2b8
[11] pry(main)> b.test NoMethodError: undefined method []' for nil:NilClass from .../.rvm/rubies/ruby-2.2.2/lib/ruby/2.2.0/ostruct.rb:185:in method_missing'
[12] pry(main)> b.test=0 NoMethodError: undefined method has_key?' for nil:NilClass from .../.rvm/gems/ruby-2.2.2/gems/recursive-open-struct-0.6.4/lib/recursive_open_struct.rb:93:in _get_key_fromtable'
[13] pry(main)> b => #RecursiveOpenStruct:0x3ff34cd4f2b8
[6] pry(main)> a=OpenStruct.new(nil) => #
[7] pry(main)> a.test => nil
[8] pry(main)> a.test = 0 => 0
[9] pry(main)> a => #
` class ResponseDeserializer class << self
end end `