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
.