Object not missing constant... what am I doing wrong?

Background: I’m using ActiveRecord to handle some bulk uploads. I
decided it would be a good idea to put all my models into subfolders,
then load them with autoload [essentially, so I can namespace
everything into a module]. Here’s the relevant code (i’m using
MODULENAMEBase.rb as the naming convention for the class that does
establish_connection):

module DBNamespace
def self.included(m)
@models_path = “models/#{m}”
require “#{@models_path}/#{m}Base.rb”
Dir.new(@models_path).entries.grep(/.rb$/).collect do |fn|
cname = fn.sub(/.rb$/, ‘’)
cname[0] = cname[0].chr.upcase
m.autoload(cname, “#{@models_path}/#{fn}”) unless fn ==
“#{m}Base.rb”
end
end

end

module PL
include DBNamespace
end


Right now, I can check PL.autoload?(:Agent) and get the correct path;
I can even load the constant with PL.const_get(:Agent). However,
trying PL::Agent gives me a:

/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/
dependencies.rb:278:in load_missing_constant': uninitialized constant PL::Agent (NameError) from /usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/ active_support/dependencies.rb:467:inconst_missing’

And doing an include PL; Agent gives me the odder:

/usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/
dependencies.rb:252:in load_missing_constant': Object is not missing constant Agent! (ArgumentError) from /usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/ active_support/dependencies.rb:467:inconst_missing’
from /usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/
active_support/dependencies.rb:479:in `const_missing’
from header.rb:7

Can anybody clear this up?

Hi,

Looks like you’re trying to reinvent something that Rails already
tries to do for you, and the two mechanisms aren’t playing nicely
together.

2008/6/18 Teleolurian [email protected]:

require “#{@models_path}/#{m}Base.rb”
module PL
PL::Agent (NameError)
from /usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/
active_support/dependencies.rb:467:in `const_missing’

This happens because when you try to access PL::Agent directly, your
PL module hasn’t been explicitely included into anything, and
therefore your included block was never called. Hence, no constant
PL::Agent.

   from header.rb:7

This is where you’re tripping over Rails’s ActiveSupport autoloading.
First you include PL, which includes DBNamespace, and calls
DBNamespace::included, and that terminates properly. At this point,
you have added Agent as autoloadable… That would (probably) be fine
in a pure Ruby application. But Rails already has an autoloading
mechanism, which is based on overriding Class#const_missing, and which
is apparently called as soon as you reference the (as yet unknown)
constant Agent. This apparantly is already known (probably due to your
manual addition of it to the autoload map).

Can anybody clear this up?

I would recommend that if you want to namespace models like this, let
Rails to the work its own way for you. Put files in a hierarchical
structure under app/models or lib/ (which are both in the load path
anyway), and name those files consistently. For example, in
db_namespace.rb, just have

Dir[“#{File.basename(FILE, ‘rb’)}/**/*.rb”].each do |requirement|
require requirement
end

and in db_namespace/agent.rb, do something like

module DBNamespace
class Agent
# stuff
end
end

Then Agent is autoloaded the first time ruby sees DBNamespace::Agent.

Apologies if I’ve missed some of the point of what you were trying to
do, but I do recommend that you stick to Rails conventions when doing
something like this, as trying to second-guess all the ActiveSupport
core extensions to Module and Class are almost guaranteed to cause
headaches.

oops, didn’t mean to double-post, sowwy.

On Jun 17, 9:50 pm, Bryan JJ Buckley [email protected] wrote:

Background: I’m using ActiveRecord to handle some bulk uploads. I
Dir.new(@models_path).entries.grep(/.rb$/).collect do |fn|
include DBNamespace
from /usr/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/

First you include PL, which includes DBNamespace, and calls

Can anybody clear this up?

Apologies if I’ve missed some of the point of what you were trying to
do, but I do recommend that you stick to Rails conventions when doing
something like this, as trying to second-guess all the ActiveSupport
core extensions to Module and Class are almost guaranteed to cause
headaches.


JJ

Thank you very much! Adding module namespaces around the model classes
was what I needed to do. Probably should have been obvious, but I’ve
just come back to ruby after a bit of a hiatus :slight_smile: