Forum: Ruby on Rails Rails namespace help requested

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Michael E. (Guest)
on 2005-12-14 16:33
(Received via mailing list)
Hi all -

I posted yesterday with the subject "namespace pollution" and with the
high traffic on this list, it's kind of disappeared and I'm in need of
a quick answer so i can move on.   To recap quickly, can someone tell
if Rails is somehow forcing all modules into a single namespace?   I
have a model class StateProvince and inside a webservice module in my
lib/ directory I have a StateProvince as well but no matter what I do
when running under Rails I get a superclass mismatch error.   This
doesn't happen when I have standalone ruby code in similar situations.

Thanks for any help
Mike
zdennis (Guest)
on 2005-12-14 17:00
(Received via mailing list)
Michael E. wrote:
>
By default Rails classes are using toplevel namespace; ie: ActiveRecord,
ActionController,
ActionView, etc..

Rails also does not put your models into a separate namespace (though i
wish it would =), and those
also are toplevel. ie: User, Account, Session, Group, Article.

If you have any classes that you wrote that have the same names as your
models or other toplevel
classes/modules that Rails is using you need to either a) rename them or
b) move them inside of
another namespace.

The problem you are having is that the first time you define/open a
class it has to define it's
superclass.

class A ; end
class B < A; end

You cannot define/open a class and then later try to subclass it, ie:

class A; end
class B; end
class B < A; end # error!!

This is the scenario you're hitting with your namespace clash. Your
StateProvince class is being
initalized, then when it gets around to loading your StateProvince
module it seems you're trying to
define inheritance, and you can't do that now.

If you have namespace clashes but you are in your namespace you can use
:: syntax to ensure you get
the toplevel class/module. For example:

class StateProvince
end

module MyNameSpace
    class StateProvince
    end

    module MoreModules
       class MyStateProvinceModel < StateProvince
       end
    end
end

In the above code code your MyStateProvinceModel is going to subclass
MyNameSpace::StateProvince
because that is the first constant ruby finds while it is looking for
"StateProvince". This may be
wrong because your MyStateProvinceModel might need to subclass the
toplevel StateProvince class.
This is where the "::" comes in handy:

class StateProvince
end

module MyNameSpace
    class StateProvince
    end

    module MoreModules
       class MyStateProvinceModel < ::StateProvince
       end
    end
end

The leading :: on any constant will force ruby to look at the most
toplevel constant.

I hope this helps more then it confuses,

Zach
zdennis (Guest)
on 2005-12-14 17:09
(Received via mailing list)
zdennis wrote:
> Michael E. wrote:

> class B; end
> class B < A; end # error!!
>
> This is the scenario you're hitting with your namespace clash. Your
> StateProvince class is being initalized, then when it gets around to
> loading your StateProvince module it seems you're trying to define
> inheritance, and you can't do that now.
>

I don't mean to say it's anything you're doing on purpose. I think ruby
finds your StateProvince
class definition first, then it finds the StateProvince model
definition, which is where it tries to
subclass ActiveRecord::Base. At this point Ruby already has a definition
for StateProvince, and
although ruby lets us reopen the class we can't subclass it because Ruby
defines the superclass of a
class when the class is first read in.

Zach
Michael E. (Guest)
on 2005-12-14 18:03
(Received via mailing list)
HI Zach -

THanks very much for your help.    I'm not sure I understand why my
clash exists though because I have this exact scenario:

class StateProvince < ActiveRecord::Base
end

# this is in a directory of lib/ws
module WebServiceModule
   class StateProvince
   end
end

Isn't the  namespace declared for the class inside the module as
::WebServiceModule::StateProvince and the Rails model as
::StateProvince?   Aren't those different objects in the eyes or Ruby?

Also I'm not doing inheritance in my WebServiceModule, I'm just
declaring a namespace right?

I'm a bit new to Ruby so it's possible I'm mixing this up but this is
what I understood from reading the pickaxe book.

Thanks again for your help.

MIke
zdennis (Guest)
on 2005-12-14 19:12
(Received via mailing list)
Michael E. wrote:
>    class StateProvince
>    end
> end
>
> Isn't the  namespace declared for the class inside the module as
> ::WebServiceModule::StateProvince and the Rails model as
> ::StateProvince?   Aren't those different objects in the eyes or Ruby?

Yes.

>
> Also I'm not doing inheritance in my WebServiceModule, I'm just
> declaring a namespace right?

In your WebServiceModule you aren't doing any explicit inheritance. From
your post from yesterday:

    but when I run my code in Rails, I get a superclass mismatch error
    when I include the module.

If you include you WebServiceModule in your top level, it will have a
problem when it finds the
StateProvince model. By saying:

    include WebServiceModule

It will move WebServiceModule::StateProvince (and all other constants)
to scope that your "include"
statement is in. In this case it is in the toplevel/global scope and it
will be accessible as
::StateProvince.

So now that it is toplevel accessible and ruby finds your StateService
model which tries to subclass
ActiveRecord::Base you get your superclass problem!

I hope this helps!

>
> I'm a bit new to Ruby so it's possible I'm mixing this up but this is
> what I understood from reading the pickaxe book.

ooh, good book. =)

Zach
Michael E. (Guest)
on 2005-12-14 22:49
(Received via mailing list)
AH!!!  Thank you!!!   I guess I needed to get whacked with a 2x4
regarding mixing in a module...The pickaxe booking didn't explain it
as concisely.    Thanks again

Mike
This topic is locked and can not be replied to.