zeitwerk follow conventional file structure which is able to load your project's classes and modules on demand (autoloading) as long as you follow it's rule.
# service/account/authenticate/base.rb
module Account
module Authenticate
puts "load service ....."
AuthenticateError = Class.new(StandardError)
class Base
end
end
end
::Account::Authenticate::AuthenticateError # uninitialized constant
::Account::Authenticate::Base # load service ....
::Account::Authenticate::AuthenticateError # OK
as you can see, the first time you attempt to reach the constant AuthenticateError, the log load service ... does not show, that because you don't play zeitwerk rule:
whenever it gets a request to load the const ::Account::Authenticate::AuthenticateError, first it'll check and return if that constant already loaded, otherwise it'll look for the file /account/authenticate/authenticate_error.rb which corresponding to the constant ::Account::Authenticate::AuthenticateError to find that constant definition, but it could not find it.
on step 2, when you call ::Account::Authenticate::Base, it could find the file /account/authenticate/base.rb and load it, during this time, it's also load the constant AuthenticateError which is defined on that file, now we have the constant ::Account::Authenticate::AuthenticateError, and of course, it's OK on step 3.
now let try to play with the zeitwerk rule, i create a file /account/authenticate/authenticate_error.rb as below
# service/account/authenticate/authenticate_error.rb
module Account
module Authenticate
puts "load error ....."
AuthenticateError = Class.new(StandardError)
end
end
and try to attempt that constant at the step 1
$ spring stop
$ rails c
> ::Account::Authenticate::AuthenticateError
load error .....
=> Account::Authenticate::AuthenticateError
it worked since zeitwerk found the file account/authenticate/authenticate_error.rb. (note that the file name /____authenticate_error.rb still work)
my thought: i think you could work safely with the constant AuthenticateError inside the module ::Account::Authenticate, in case of you want to expose those error constants to outside, you could create file /account/authenticate/error.rb
# service/account/authenticate/error.rb
module Account
module Authenticate
module Error
AuthenticateError = Class.new(StandardError)
end
end
end
then you could access ::Account::Authenticate::Error::AuthenticateError, in my opinion, it even clearer than put AuthenticateError inside base.rb.