开发者

What is the relationship between a ruby class and module with the same name?

开发者 https://www.devze.com 2023-02-09 11:54 出处:网络
In my rails app I have a models/foo.rb and models/foo/exceptions.rb: class Foo include Foo::Exceptions end

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
  1. What do you think of my file structure / namespacing?
  2. Is my inclusion line in Foo necessary, or does Rails a开发者_开发技巧utoinclude those modules?
  3. Why does MySpecialException exist in the top level Foo namespace and point to Foo::Exceptions::MySpecialException?
  4. 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).


  1. I suggest that you move exceptions to lib: lib/exceptions/exception_name.rb
  2. 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/**/"]

0

精彩评论

暂无评论...
验证码 换一张
取 消