Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

private method `inherited' called for Object:Class (NoMethodError) #14

Closed
d11wtq opened this Issue · 9 comments

3 participants

@d11wtq

Just updated from 0.0.3 to 0.0.4 and getting this error when my app starts up. I'll take a closer look tomorrow as I'm doing something else now and it's nearly 3am ;)

/home/chris/.rvm/gems/ruby-1.9.2-p180@flippa/gems/virtus-0.0.4/lib/virtus/support/descendants_tracker.rb:15:in `inherited': private method `inherited' called for Object:Class (NoMethodError)
    from /home/chris/.rvm/gems/ruby-1.9.2-p180@flippa/gems/virtus-0.0.4/lib/virtus/attribute.rb:118:in `inherited'
    from /home/chris/.rvm/gems/ruby-1.9.2-p180@flippa/gems/virtus-0.0.4/lib/virtus/attribute/object.rb:5:in `<class:Attribute>'
    from /home/chris/.rvm/gems/ruby-1.9.2-p180@flippa/gems/virtus-0.0.4/lib/virtus/attribute/object.rb:2:in `<module:Virtus>'
    from /home/chris/.rvm/gems/ruby-1.9.2-p180@flippa/gems/virtus-0.0.4/lib/virtus/attribute/object.rb:1:in `<top (required)>'
    from /home/chris/.rvm/gems/ruby-1.9.2-p180@flippa/gems/virtus-0.0.4/lib/virtus.rb:66:in `require'
    from /home/chris/.rvm/gems/ruby-1.9.2-p180@flippa/gems/virtus-0.0.4/lib/virtus.rb:66:in `<top (required)>'
@dkubb
Collaborator

@d11wtq Can you check and see if your Object class has a descendants singleton/class method defined on it?

If so, then we probably need to change the logic here https://github.com/solnic/virtus/blob/master/lib/virtus/support/descendants_tracker.rb#L15 to something like:

superclass.inherited(descendant) unless superclass.equal?(::Object)

Can you also try editing virtus locally to use the above line in place and see if the problem persists?

@dkubb
Collaborator

@d11wtq Also if your Object class does have descendants as a singleton/class method, are you using ActiveSupport or some other library that might be messing with Object directly?

It's no big deal if you are, all it means is that we're going to have to be more aware of libraries doing crazy things like this.

@d11wtq

Thanks for the quick response! We're using Rails, so ActiveSupport is included, correct. http://api.rubyonrails.org/classes/ActiveSupport/DescendantsTracker.html

Your fix worked. I guess it's dangerous to have both gems adding the same methods in different ways.

PS: Where is it actually defined as private? All I see is the doc comment @private o_O

@dkubb dkubb closed this issue from a commit
@dkubb dkubb Added DescendantsTracker#add_descendant
* Instead of calling inherited explicitly, call a method that explicitly
  adds the descendants. This avoids some of the problems where a class like
  Object might have .descendants monkey-patched in. It also allows the
  inherited hook to be private, which it is in Object.

Fixes #14
5537b3f
@dkubb dkubb closed this in 5537b3f
@dkubb
Collaborator

@d11wtq I fixed this a slightly different way. Could you confirm by testing out edge and let me know if it fixes the problem for you?

@d11wtq

Confirmed, thanks :)

@dkubb
Collaborator

@solnic do you think we should do a 0.0.5 release to fix this problem for people using ActiveSupport?

Also do you think I should add a spec that reproduces the messed up AS behaviour of adding methods to ::Object that we were checking for? I usually only add specs to repro actual bugs in my software, not repro bugs in other people's software that my (perfectly valid) code was tripped up by.

@dkubb
Collaborator

@d11wtq btw to answer your question earlier about where the method is defined as private, I just checked and Object.inherited itself is a private method. I'm a little surprised by that though since you never see people marking their inherited hooks as private also and it's usually convention to use the same visibility as the superclass' method. Maybe people don't know about it, or maybe they don't use private_class_method very often.

I also see that Module.included and Module.extended are also private. I did not know that either.

Given this new insight I'm going to make sure my own inherited, included, and extended methods are private to match the ruby conventions, and make it less likely I will be calling them directly (not that it's a normal thing, but I was doing it in Virtus::DescendantsTracker before this issue was reported.

@solnic
Owner

@dkubb yeah I'm gonna push 0.0.5 with the fix

Just wanted to make sure I understand the problem - it was caused by a) AS that adds "descendants" to ::Object b) virtus which had "inherited" defined as a public method

Right?

I don't we need a separate spec for this.

@dkubb
Collaborator

@solnic yeah, that's correct. The real problem has more to do with "a" though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.