On Sun, Dec 11, 2011 at 3:04 PM, Frederick C. <
[email protected]> wrote:
module Y
Thanks for the very interesting explanation.
If I understand your reasoning correctly, the logic would be that
in the cases with separate module definitions:
- module X::Y::Z is loaded from the file …/lib/x/y/z.rb
- this implicitely also defines the constant X::Y
(based solely on information in file …/lib/x/y/z.rb
and not trying to read …/lib/x/y.rb)
- when X::Y is used later on, it is never really loaded from the
file …/lib/x/y.rb , so what is defined there can be
mysteriously missing (depending on the order modules where loaded).
However, I could not produce this behavior as I understood it.
As a test, I made 2 implementations of the module in ./lib/x/y/z.rb
In both cases I have in …/lib/x/y.rb
…/lib/x$ cat y.rb
puts “loading module X / module Y in file …/lib/x/y.rb”
module X
module Y
end
end
Test 1: separate module definitions
…/lib/x/y$ cat z.rb
module X
module Y
module Z
def self.foo
“Z.foo”
end
end
end
end
Results:
$ rails c
Loading development environment (Rails 3.1.3)
001:0> ActiveSupport::Dependencies.logger = Rails.logger #=> <…>
002:0> ActiveSupport::Dependencies.log_activity=true #=> true
003:0> X::Y::Z
loading module X / module Y in file …/lib/x/y.rb
=> X::Y::Z
in logfile:
Dependencies: called load_missing_constant(Object, :X)
Dependencies: called load_missing_constant(X, :Y)
Dependencies: called require_or_load("…/lib/x/y.rb", nil)
Dependencies: loading …/lib/x/y
Dependencies: called load_file("…/lib/x/y.rb", [“X::Y”, “Y”])
Dependencies: called new_constants_in(“X”, :Object)
Dependencies: New constants: X::Y
Dependencies: loading …/lib/x/y.rb defined X::Y
Dependencies: called load_missing_constant(X::Y, :Z)
Dependencies: called require_or_load("…/lib/x/y/z.rb", nil)
Dependencies: loading …/lib/x/y/z
Dependencies: called load_file("…/lib/x/y/z.rb", [“X::Y::Z”, “Y::Z”,
“Z”])
Dependencies: called new_constants_in(“X::Y”, “Y”, :Object)
Dependencies: New constants: X::Y::Z
Dependencies: loading …/lib/x/y/z.rb defined X::Y::Z
Test 2: (in 1 direct line module X::Y::Z)
…/lib/x/y$ cat z.rb
module X::Y::Z
def self.foo
“Z.foo”
end
end
Results:
$ rails c
Loading development environment (Rails 3.1.3)
001:0> ActiveSupport::Dependencies.logger = Rails.logger #=> <…>
002:0> ActiveSupport::Dependencies.log_activity=true #=> true
003:0> X::Y::Z
loading module X / module Y in file …/lib/x/y.rb
=> X::Y::Z
In logifle:
Dependencies: called load_missing_constant(Object, :X)
Dependencies: called load_missing_constant(X, :Y)
Dependencies: called require_or_load("…/lib/x/y.rb", nil)
Dependencies: loading …/lib/x/y
Dependencies: called load_file("…/lib/x/y.rb", [“X::Y”, “Y”])
Dependencies: called new_constants_in(“X”, :Object)
Dependencies: New constants: X::Y
Dependencies: loading …/lib/x/y.rb defined X::Y
Dependencies: called load_missing_constant(X::Y, :Z)
Dependencies: called require_or_load("…/lib/x/y/z.rb", nil)
Dependencies: loading …/lib/x/y/z
Dependencies: called load_file("…/lib/x/y/z.rb", [“X::Y::Z”, “Y::Z”,
“Z”])
Dependencies: called new_constants_in(“X::Y”, “Y”, :Object)
Dependencies: New constants: X::Y::Z
Dependencies: loading …/lib/x/y/z.rb defined X::Y::Z
So, my experiments seem to suggest that in both cases
that I tried, there is an explicit order where all intermediate
modules are loaded in turn (with load_missing_constants),
even if only the deepest module would be strictly required to
evaluate X::Y::Z
Could you show an example of where the problem you described
occurs. Or maybe this behavior has changed recently?
Thanks,
Peter