Module: Wright::Util::RecursiveAutoloader Private

Defined in:
lib/wright/util/recursive_autoloader.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Recursive autoloader, recursively adds autoloads for all files in a directory.

Class Method Summary collapse

Class Method Details

.add_autoloads(directory, parent_class) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Adds autoloads for all files in a directory to a parent class.

Registers all files in directory to be autoloaded the first time ParentClass::CamelCased::FileName is accessed.

Examples:

require 'fileutils'

# set up a test directory
FileUtils.cd '/tmp'
FileUtils.mkdir_p 'somedir/foo'
File.write('somedir/foo/bar_baz.rb', 'class Root::Foo::BarBaz; end')

# define a root class, add an autoload
class Root; end
Wright::Util::RecursiveAutoloader.add_autoloads('somedir', 'Root')

# Root::Foo::BarBaz is going to be autoloaded
Root::Foo.autoload? 'BarBaz'
# => "/tmp/somedir/foo/bar_baz.rb"

# instantiate Root::Foo::BarBaz, somedir/foo/bar_baz.rb is loaded
foo_bar_baz = Root::Foo::BarBaz.new
foo_bar_baz.class
# => Root::Foo::BarBaz

# at this point, somedir/foo/bar_baz.rb has already been loaded
Root::Foo.autoload? 'BarBaz'
# => nil

Parameters:

  • directory (String)

    the path of the directory containing the files to be autoloaded

  • parent_class (String)

    the parent class to add the autoloads to

Raises:

  • (ArgumentError)

    if the parent class cannot be resolved


45
46
47
48
49
50
# File 'lib/wright/util/recursive_autoloader.rb', line 45

def self.add_autoloads(directory, parent_class)
  unless class_exists?(parent_class)
    fail ArgumentError, "Can't resolve parent_class #{parent_class}"
  end
  add_autoloads_unsafe(directory, parent_class)
end

.add_autoloads_for_current_dir(parent_class) ⇒ Object (private)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


52
53
54
55
56
57
58
# File 'lib/wright/util/recursive_autoloader.rb', line 52

def self.add_autoloads_for_current_dir(parent_class)
  klass = Wright::Util::ActiveSupport.constantize(parent_class)
  Dir['*.rb'].each do |filename|
    classname = "#{Wright::Util.filename_to_classname(filename)}"
    klass.autoload classname, ::File.expand_path(filename)
  end
end

.add_autoloads_unsafe(directory, parent_class) ⇒ Object (private)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/wright/util/recursive_autoloader.rb', line 74

def self.add_autoloads_unsafe(directory, parent_class)
  Dir.chdir(directory) do
    add_autoloads_for_current_dir(parent_class)
    Dir['*/'].each do |dir|
      subclass = Wright::Util.filename_to_classname(dir)
      ensure_subclass_exists(parent_class, subclass)
      new_parent = Wright::Util.filename_to_classname(
        ::File.join(parent_class, dir))
      add_autoloads_unsafe(dir, new_parent)
    end
  end
end

.class_exists?(classname) ⇒ Boolean (private)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)

69
70
71
# File 'lib/wright/util/recursive_autoloader.rb', line 69

def self.class_exists?(classname)
  !Wright::Util::ActiveSupport.safe_constantize(classname).nil?
end

.ensure_subclass_exists(classname, subclass) ⇒ Object (private)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


61
62
63
64
65
66
# File 'lib/wright/util/recursive_autoloader.rb', line 61

def self.ensure_subclass_exists(classname, subclass)
  complete_classname = "#{classname}::#{subclass}"
  return true if class_exists?(complete_classname)
  klass = Wright::Util::ActiveSupport.constantize(classname)
  klass.const_set(subclass, Class.new)
end