On Fri, Feb 8, 2013 at 4:03 PM, Xavier Noria <[email protected]> wrote:

> On Fri, Feb 8, 2013 at 3:18 PM, Rodrigo Rosenfeld Rosas
> <[email protected]> wrote:
>
> > Em 08-02-2013 12:06, Xavier Noria escreveu:
> >
> >> Seems unrelated to dependencies.rb, most likely a missing require
> >> somewhere within Rails.
> >>
> >> It can be the case that it does not show up in production because of
> eager
> >> loading.
> >
> >
> > Any ideas why helpers.rb is loaded when you write code like below?
> >
> > module ActionView
> >   module Helpers
> >     module NumberHelper
> >
> > Is this normal MRI behavior or is this caused by dependencies.rb?
>
> Ruby on Rails itself does not use dependencies.rb to load its code. It
> is a regular Ruby library that uses requires and Kernel#autoload with
> some added sugar. AS::Dependencies only covers application constant
> autoloading.
>
> The thing goes like this: When an application boots in any environment
> action_view.rb is loaded. When that file is executed an autoload for
> :Helpers is configured under ActionView. In a default setup,
> helpers.rb is not yet loaded. That is, if you run
>
>     rails runner 1
>
> helpers.rb is not loaded (at least in 3-2-stable, not that we are
> explaining any contract, only load order execution to follow what
> happens in your exception).
>
> But if you force the evaluation of the constant as in your example above:
>
>     module ActionView
>       module Helpers
>         ...
>       end
>     end
>
> that autoload is triggered because the interpreter checks whether
> "Helpers" is a constant defined in the module object stored in
> ActionView. Therefore, helpers.rb is interpreted and sets in turn an
> autoload for NumberHelper below AV::Helpers.
>
> So, module Helpers in that snippet *reopens* a module object defined
> via the autoload, rather than creating the module object. The
> execution follows and the same happens with the "NumberHelper"
> constant down below. The interpreter checks whether it belongs to the
> module object stored in AV::Helpers. Since it is unknown and there is
> an autoload for it it gets triggered, and loads... well the very
> number_helper.rb whose execution we were in the middle of (not sure
> this sentence is valid English :).
>
>
I think I was fighting the same bug some time ago ...

(the resolution for me to avoid any explicit use of
'require' in the application and depend fully on autoloading).

Doing what amounts to a "circular" call of 'require' triggers it. The
second time around, it seems to have forgotten the results of the
earlier require (IIRC, the second call to require is not really executed,
(correct, because it was already executed), but the result of the require
seems to be forgotten ...) and then later on, when that module is called,
I got an

  uninitialized constant

exception.

Only occurs in development (not in test or production),
actually with WEBrick.

app/models $ head -10 sparql.rb
#
#
#
#
#
#

require 'sparql/query'

module Sparql


app/models $ head -12 sparql/query.rb
#
#
#
#
#
#

module Sparql

  class Query

    include Sparql::Helper



app/models $ head -12 sparql/helper.rb
#
#
#
#
#
#

require 'sparql'

module Sparql
  module Helper



Yields:

uninitialized constant Sparql::Helper

Rails.root: ... demo-001
Application Trace <http://localhost:3000/#> | Framework
Trace<http://localhost:3000/#>
 | Full Trace <http://localhost:3000/#>

app/models/sparql.rb:14:in `singletonclass'
app/models/sparql.rb:12:in `<module:Sparql>'
app/models/sparql.rb:10:in `<top (required)>'
app/models/sparql/helper.rb:8:in `<top (required)>'
app/models/sparql/query.rb:12:in `<class:Query>'
app/models/sparql/query.rb:10:in `<module:Sparql>'
app/models/sparql/query.rb:8:in `<top (required)>'
app/models/sparql.rb:8:in `<top (required)>'


The 'require' statements are actually not required if all files are
in the correct place for autoloading and then this issue completely
disappears.

HTH,

peter_v



> I suspect there is a circularity here that is showing up that way.
>
> Would need to dig deeper to fully explain how this ends up in an
> exception, maybe I'll do it tonight, but in the meantime here's some
> context in case it helps.
>

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to