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

SystemStackLevel exception if Hashie::Extensions::Coercion is included in parent class and coercion target #202

Closed
maxlinc opened this issue Aug 14, 2014 · 1 comment

Comments

@maxlinc
Copy link
Contributor

maxlinc commented Aug 14, 2014

Problem:

I came across a situation where coercion blows up with a nasty and cryptic error:

  1) Hashie::Extensions::Coercion#coerce_key nesting coeces nested objects
     Failure/Error: Unable to find matching line from backtrace
     SystemStackError:
       stack level too deep
     # ./lib/hashie/extensions/coercion.rb:14

I found it while working on coercions for core types, but I verified the problem exists on master.

Test:

    context 'nesting' do
      class BaseCoercableHash < Hash
        include Hashie::Extensions::Coercion
        include Hashie::Extensions::MergeInitializer
      end

      class NestedCoercableHash < BaseCoercableHash
        include Hashie::Extensions::Coercion
        include Hashie::Extensions::MergeInitializer
        # coerce_key :foo, Integer
      end

      class RootCoercableHash < BaseCoercableHash
        include Hashie::Extensions::Coercion
        include Hashie::Extensions::MergeInitializer
        coerce_key :nested, NestedCoercableHash
      end

      subject { RootCoercableHash }
      let(:instance) { subject.new }

      it 'coeces nested objects' do
        subject.coerce_key :nested, NestedCoercableHash

        instance[:nested] = { foo: '123' }
        expect(instance[:nested]).to be_a(NestedCoercableHash)
        # expect(instance[:nested][:foo]).to be_an(Integer)
        # expect(instance[:nested][:foo]).to eq('123')
      end
    end

Workaround:

Remove include Hashie::Extensions::Coercion from the subclasses so it's only in BaseCoercableHash.

That's more DRY anyways, but I don't think it's illegal to include the same module twice... in fact I just tested and you can also create this error by including Hashie::Extensions::Coercion twice in the base class, while including Hashie::Extensions::MergeInitializer twice doesn't cause a problem.

Solution?:

Ideally this code should work, or at least raise a more useful specific error.

If that's not possible it could just be documented as a known issue.

@dblock
Copy link
Member

dblock commented Aug 17, 2014

This looks like a legit problem, would appreciate a PR with a fix, or even with just the test that reproduces the issue as above turned into a PR.

@dblock dblock closed this as completed in 74f26fd Aug 21, 2014
dblock added a commit that referenced this issue Aug 21, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants