diff --git a/README.md b/README.md index e155481..5774a1a 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,23 @@ ros = RecursiveOpenStruct.new(h, preserve_original_keys: true) ros.to_h # => { 'fear' => 'is', 'the' => 'mindkiller' } ``` +### Optional: Raise error on missing attribute + +This option allows to raise an error if you try to call an attribute you didn't specify in hash + +```ruby +h = { 'fear' => 'is', 'the' => 'mindkiller' } } +ros = RecursiveOpenStruct.new(h, raise_on_missing: true) +ros.undefined # => undefined method `undefined' for # +``` + +The default behaviour returns nil + +```ruby +h = { 'fear' => 'is', 'the' => 'mindkiller' } } +ros = RecursiveOpenStruct.new(h) +ros.undefined # => nil +``` ## Installation diff --git a/lib/recursive_open_struct.rb b/lib/recursive_open_struct.rb index 184e5ef..3850ebd 100644 --- a/lib/recursive_open_struct.rb +++ b/lib/recursive_open_struct.rb @@ -23,7 +23,8 @@ def self.default_options { mutate_input_hash: false, recurse_over_arrays: false, - preserve_original_keys: false + preserve_original_keys: false, + raise_on_missing: false } end @@ -124,6 +125,10 @@ def method_missing(mid, *args) if @table.key?(_get_key_from_table_(key)) new_ostruct_member!(key) public_send(mid) + elsif @options[:raise_on_missing] + err = NoMethodError.new "undefined method `#{mid}' for #{self}", mid, args + err.set_backtrace caller(1) + raise err end else err = NoMethodError.new "undefined method `#{mid}' for #{self}", mid, args diff --git a/spec/recursive_open_struct/indifferent_access_spec.rb b/spec/recursive_open_struct/indifferent_access_spec.rb index 5b86740..c62400c 100644 --- a/spec/recursive_open_struct/indifferent_access_spec.rb +++ b/spec/recursive_open_struct/indifferent_access_spec.rb @@ -160,6 +160,30 @@ end end + context 'when undefined method' do + context 'when raise_on_missing is enabled' do + subject(:recursive) { RecursiveOpenStruct.new(recursive_hash, raise_on_missing: true) } + let(:recursive_hash) { {:foo => [ {'bar' => [ { 'foo' => :bar} ] } ] } } + + specify 'raises NoMethodError' do + expect { + recursive.undefined_method + }.to raise_error(NoMethodError) + end + end + + context 'when raise_on_missing is disabled' do + context 'preserves the original keys' do + subject(:recursive) { RecursiveOpenStruct.new(recursive_hash) } + let(:recursive_hash) { {:foo => [ {'bar' => [ { 'foo' => :bar} ] } ] } } + + specify 'returns nil' do + expect(recursive.undefined_method).to be_nil + end + end + end + end + end end