In my rails app I have a models/foo.rb and models/foo/exceptions.rb:
class Foo
include Foo::Exceptions
end
module Foo::Exceptions
class MySpecialException < Exception
end
end
At the rails console, I then see this:
>> Foo::MySpecialException
Foo::Exceptions::MySpecialException < Exception
>> Foo::MySpecialException == Foo::Exceptions::MySpecialException
true
>> Foo::MySpecialException === Foo::Exceptions::MySpecialException
false
- What do you think of my file structure / namespacing?
- Is my inclusion line in
Foo
necessary, or does Rails a开发者_开发技巧utoinclude those modules? - Why does
MySpecialException
exist in the top levelFoo
namespace and point toFoo::Exceptions::MySpecialException
? - What does it mean that those two classes are
==
but not===
?
I explored this in irb but kept running into errors that were inconsistent with the behavior I (think) I've seen in Rails.
related: What is a conventional place to keep custom Exception definitions in a rails project?
What is the relationship between a ruby class and module with the same name?
A class and a module can't have the same fully qualified name in ruby. It's possible to have a class Foo::Bar
and a module Baz::Bar
, in which case there is no relation between the class and the module. However it is not possible to both have class Foo::Bar
and a module Foo::Bar
at the same time.
(I'm not sure what this has to do with the rest of your question though)
Is my inclusion line in Foo necessary, or does Rails autoinclude those modules?
Rails will not automatically include your modules. However that does not mean it's necessary to include yourself, you could just access it qualified. I.e. use Exceptions::MySpecialException
instead of just MySpecialException
inside the Foo
class.
Why does MySpecialException exist in the top level Foo namespace and point to Foo::Exceptions::MySpecialException?
Because you included Foo::Exceptions
into Foo
. Because of that all instance methods of Foo::Exceptions
are also instance methods of Foo
and all constants of Foo::Exceptions
are also constants of Foo
- including MySpecialException
.
What does it mean that those two classes are == but not ===?
==
means that it's the same class. That it's not ===
means that the class is not an instance of itself (since x === y
is the same as y.is_a?(x)
if x
is a class).
- I suggest that you move exceptions to lib: lib/exceptions/exception_name.rb
Rails will auto load stuff in models dir, however for the lib folder, you gotta tell to do so by checking config/application.rb and adding this:
# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
精彩评论