class Autoloaded::Autoloader
Autoloads files in a source directory.
@since 1.3
Attributes
The source code context in which autoloading is to occur.
@return [Binding]
@see autoload!
@api private
Public Class Methods
Constructs a new Autoloader with the specified host_binding.
@param [Binding] host_binding
a value for #host_binding
@raise [ArgumentError] host_binding is nil
@api private
# File lib/autoloaded/autoloader.rb, line 30 def initialize(host_binding) raise(::ArgumentError, "can't be nil") if host_binding.nil? @host_binding = host_binding @specifications = Specifications.new end
Public Instance Methods
Issues autoload
statements for source files found in #from. The constants are renamed by #with and #only. The source files are filtered by #except and #only.
@return [Array of Array] the arguments passed to each autoload
statement
made
@see ruby-doc.org/core/Module.html#method-i-autoload Module#autoload @see ruby-doc.org/core/Kernel.html#method-i-autoload Kernel#autoload @see from
@see except @see only @see with
@api private
# File lib/autoloaded/autoloader.rb, line 52 def autoload! result = [] from_load_pathed_directory.each_source_filename do |source_filename| source_basename = ::File.basename(source_filename) next if specifications.except.any? { |spec| spec.match source_basename } unless specifications.only.empty? || specifications.only.any? { |spec| spec.match source_basename } next end first_match = (specifications.with + specifications.only).inject(nil) do |match, spec| match || spec.match(source_basename) end constant_names = Array(first_match || Inflection.to_constant_name(source_basename)) existing_source_filenames = constant_names.collect do |const| existing_autoload? const end if existing_source_filenames.all? { |file| file == source_filename } next end existing_source_filenames.zip(constant_names).each do |file, const| if file Warning.changing_autoload constant_name: constant_full_name(const), old_source_filename: file, new_source_filename: source_filename, host_source_location: host_source_location end end if existing_source_filenames.compact.empty? constant_names.each do |const| next unless existing_constant?(const) # Don't warn about an existing MyAwesomeGem::VERSION constant since # probably it was loaded by a `require 'my_awesome_gem/version'` # statement in 'my_awesome_gem.gemspec'. next if (const == :VERSION) Warning.existing_constant constant_name: constant_full_name(const), source_filename: source_filename, host_source_location: host_source_location end end constant_names.each do |const| establish_autoload const, source_filename result << [const, source_filename] end end result end
The directory from which source files are autoloaded.
Defaults to the directory corresponding to the +__FILE__+ of #host_binding. For example, if eval('__FILE__', host_binding)
evaluates to +‘/absolute/path/to/my_awesome_gem.rb’+, then the default value of #from is +‘/absolute/path/to/my_awesome_gem’+.
@param [String] value a source directory path; optional
@return [String] if value is nil
, the source directory @return [Autoloader] if value is not nil
, the Autoloader
@raise [ArgumentError] value is a relative path
@see autoload!
@see host_binding
# File lib/autoloaded/autoloader.rb, line 215 def from(value=nil) if value.nil? return (instance_variable_defined?(:@from) && @from && @from.path) || default_from end # Validate value. @from = LoadPathedDirectory.new(value) self end
Private Instance Methods
# File lib/autoloaded/autoloader.rb, line 231 def constant_full_name(constant_name) "#{host_eval 'name rescue nil'}::#{constant_name}" end
# File lib/autoloaded/autoloader.rb, line 235 def default_from filename = host_source_filename dirname = ::File.dirname(filename) basename = ::File.basename(filename, ::File.extname(filename)) ::File.join dirname, basename end
# File lib/autoloaded/autoloader.rb, line 242 def establish_autoload(constant_name, source_filename) host_eval "autoload #{constant_name.to_sym.inspect}, #{source_filename.inspect}" end
# File lib/autoloaded/autoloader.rb, line 246 def existing_autoload?(constant_name) host_eval "autoload? #{constant_name.to_sym.inspect}" end
# File lib/autoloaded/autoloader.rb, line 250 def existing_constant?(constant_name) host_eval "constants.include? #{constant_name.to_sym.inspect}" end
# File lib/autoloaded/autoloader.rb, line 254 def from_load_pathed_directory (instance_variable_defined?(:@from) && @from) || LoadPathedDirectory.new(default_from) end
# File lib/autoloaded/autoloader.rb, line 259 def host_eval(statement) # TODO: Why does adding the third and fourth arguments break Kernel#eval ? # ::Kernel.eval statement, host_binding, __FILE__, __LINE__ ::Kernel.eval statement, host_binding end
# File lib/autoloaded/autoloader.rb, line 265 def host_source_filename if host_binding.respond_to?(:source_location) host_eval "::File.expand_path '#{host_binding.source_location.first}'" else host_eval '::File.expand_path __FILE__' end end
# File lib/autoloaded/autoloader.rb, line 273 def host_source_location if host_binding.respond_to?(:source_location) host_binding.source_location else host_eval('[__FILE__, __LINE__]') end.collect(&:to_s).join ':' end