Module: LoadGlob

Defined in:
lib/load_glob.rb

Overview

– Copyright ©2009 Tony Arcieri You can redistribute this under the terms of the MIT license See file LICENSE for details ++

Instance Method Summary collapse

Instance Method Details

#load_glob(glob) ⇒ Object

Load all files matching the given glob, handling dependencies between the files gracefully



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/load_glob.rb', line 10

def load_glob(glob)
  files = Dir[glob].map { |file| File.expand_path file }
          
  begin
    failed = []
    first_name_error = nil
    
    # Attempt to load each file, rescuing which ones raise NameError for
    # undefined constants.  Keep trying to successively reload files that 
    # previously caused NameErrors until they've all been loaded or no new
    # files can be loaded, indicating unresolvable dependencies.
    files.each do |file|
      begin
        require file
      rescue NameError => ex
        failed << file
        first_name_error ||= ex
      rescue ArgumentError => ex
        # Work around ActiveSuport freaking out... *sigh*
        #
        # ActiveSupport sometimes throws these exceptions and I really
        # have no idea why.  Code loading will work successfully if these
        # exceptions are swallowed, although I've run into strange 
        # nondeterministic behaviors with constants mysteriously vanishing.
        # I've gone spelunking through dependencies.rb looking for what 
        # exactly is going on, but all I ended up doing was making my eyes 
        # bleed.
        #
        # FIXME: If you can understand ActiveSupport's dependencies.rb 
        # better than I do I would *love* to find a better solution
        raise ex unless ex["is not missing constant"]
        STDERR.puts "Warning: load_glob swallowed ActiveSupport 'is not missing constant' error"
        STDERR.puts ex.backtrace[0..9]
      end
    end
    
    # If this pass didn't resolve any NameErrors, we've hit an unresolvable
    # dependency, so raise one of the exceptions we encountered.
    if failed.size == files.size
      raise first_name_error
    else
      files = failed
    end
  end until failed.empty?
  
  true
end