Ruby 2.7 adds inherit as an optional argument to Module#autoload?


Module#autoload

This method registers a file path for the given class or module and lazily loads the module the first time it is accessed.

For Example:

# person.rb
module Person
  autoload(:Profile, './profile.rb')

  puts "Profile is not loaded"
  Profile
  puts "Profile has been loaded"
end

# profile.rb
module Profile
  puts "Profile is loading"
end

Now let’s run person.rb

> ruby person.rb
Profile is not loaded
Profile is loading
Profile has been loaded

Module#autoload?

This method returns the registered file path if the module is not loaded and nil if the module has already been loaded.

# person.rb
module Person
  autoload(:Profile, './profile.rb')

  p autoload?(:Profile)
  Profile
  p autoload?(:Profile)
end

# profile.rb
module Profile
  puts "Profile is loading"
end
> ruby person.rb
"./profile.rb"
The module Profile is loading!
nil

From the above example, we can see that first autoload? call returns the registered file path. Calling Profile will load the module. Thus the second autoload? call returns nil because the module is already loaded.

Now, let’s take an example of inheritance.

# person.rb
class User
  autoload(:Profile, './profile.rb')
end

# manager.rb
class Manager < User
  p autoload?(:Profile)
end

# profile.rb
module Profile
end
> ruby manager.rb
"./profile.rb"

autoload? call from Manager class returns the file path of Profile as it is defined in the parent class. autoload directives are inherited from parent classes. But there is no way to check whether autoload is defined in the child class or not.

Ruby 2.7 has added an optional argument inherit to autoload? similar to Module#const_defined?. The value of inherit can be true or false with the default being true.

The new method signature is autoload?(CONSTANT_NAME, inherit = true).

# manager.rb
class Manager < User
  p autoload?(:Profile)
  p autoload?(:Profile, false)
end

> ruby manager.rb
"./profile.rb"
nil

First call of autoload? returns the file path because autoload is defined in the parent class. Second call returns nil because we have passed option inherit as false so it doesn’t check the constant in ancestors.