Re: Unnecessary exception raised in AS::Dependencies.load_missing_constant

Yehuda Katz
2010-02-15T12:11:56Z

Yehuda Katz
Developer | Engine Yard
(ph) 718.877.1325


On Mon, Feb 15, 2010 at 12:10 AM, Andrew White
<andyw@pixeltrix.co.uk>wrote:

> On 15 Feb 2010, at 01:32, Yehuda Katz wrote:
>
> > What I''d like to understand is what the various cases are
that could
> trigger this branch. In particular, I''m interested in
understanding the
> cases without reference to ActiveRecord (which it looks like you and others
> have started to do).
>
> Well googling for "is not missing constant" turns up a few hits:
> http://www.google.com/search?q=%22is+not+missing+constant%22
>
> The problem about trying to separate the issue from ActiveRecord is that AR
> is the going to be the vast majority of cases, however here''s
another
> situation where it arises:
>
> class Admin::User < ActiveRecord::Base
>  def self.authenticate
>    first
>  end
> end
>
> class Admin::UsersController < ApplicationController
>
>  before_filter :authenticate
>
>  def index
>    @users = User.all
>  end
>
>  private
>
>    def authenticate
>      @current_user = User.authenticate
>    end
>
> end
>
> Now this can be worked around by specifying Admin::User instead of User but
> the fact that the authenticate before_filter works and then it fails at the
> User.all call is extremely confusing to anyone who doesn''t
understand the
> error. Without the AS::Dependencies magic you''d get a NameError as
the User
> constant doesn''t exist in the Admin::UsersController namespace.
Either we
> need to not search upwards (not sure what that''d break) or we need
to search
> upwards in a consistent manner.
>
> Looking at it a bit deeper it seems as though there''s a bit of
confusion
> about what''s the right thing to do within AS::Dependencies as the
check at:
>
>
>
http://github.com/rails/rails/blob/master/activesupport/lib/active_support/dependencies.rb#L453
>
> would seem to be trying to prevent returning constants defined in parents
> but the const_missing method catches the NameError and tries to load the
> constant from the parent anyway and in doing so triggers the "is not
missing
> constant" exception.
>
> > It seems reasonable to remove the exception, but I''d like to
see what the
> original case was that caused the exception to be added in the first place.
> Presumably, it was added in order to catch a common (but infuriating) case
> of some kind.
>
> Spent an hour digging through dev.rubyonrails.org to try and find a ticket
> that references changeset 4779 but came up blank, so we''ll only
get to hear
> the reason from Nick Seckar if he''s still about. I did find ticket
6272 (
> http://dev.rubyonrails.org/ticket/6272) which has some more discussion
> about the issues. The ticket is marked as wontfix due to the fact that the
> nesting of Foo::Bar isn''t always ["Foo::Bar",
"Foo"], but your recent
> changes make that assumption so I don''t think the resolution is
valid. Also
> the fact that the raise can be triggered by errors elsewhere leading to
> hours of fruitless debugging needs to be addressed in some way I feel.
>

I''ll review this in the morning but I just want to point out that my
changing only make the nesting EXPLICIT in the code. Rails has no way to
determine the true nesting (I have an open ticket with ruby-core to address
this issue in 1.9). My changes normalize the following two cases:

class Foo
  class Bar
    Baz # previously looked in "foo/bar/baz.rb" and
"foo/baz.rb"
  end
end

module Foo
  module Bar
    Baz # previously looked in "foo/bar/baz.rb"
  end
end

I couldn''t think of or find any reason for these cases to be different.
My
guess is that the behavior was added to classes at some point (due to STI
needs) but never added to modules (since it never came up). In any event,
there''s no way to deal with:

module Foo
  module Bar
    Baz # should look in "foo/bar/baz.rb" and "foo/baz.rb"
  end
end

module Foo::Bar
  Baz # should look in "foo/bar/baz.rb"
end

unless the fix I proposed to ruby-core is accepted.


>
>
> Andrew White
>
> --
> You received this message because you are subscribed to the Google Groups
> "Ruby on Rails: Core" group.
> To post to this group, send email to rubyonrails-core@googlegroups.com.
> To unsubscribe from this group, send email to
>
rubyonrails-core+unsubscribe@googlegroups.com<rubyonrails-core%2Bunsubscribe@googlegroups.com>
> .
> For more options, visit this group at
> http://groups.google.com/group/rubyonrails-core?hl=en.