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
Michael Engelhart wrote:> 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. >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 wrote:> Michael Engelhart wrote:> > 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. >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
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 On 12/14/05, zdennis <zdennis-aRAREQmnvsAAvxtiuMwx3w@public.gmane.org> wrote:> zdennis wrote: > > Michael Engelhart wrote: > > > > > 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. > > > > 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 > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Michael Engelhart wrote:> 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?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
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 On 12/14/05, zdennis <zdennis-aRAREQmnvsAAvxtiuMwx3w@public.gmane.org> wrote:> Michael Engelhart wrote: > > 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? > > 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 > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >