autoloader 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/README +46 -0
  2. data/lib/autoloader.rb +105 -0
  3. metadata +56 -0
data/README ADDED
@@ -0,0 +1,46 @@
1
+ A couple of handy features to enhance Kernel#autoload.
2
+
3
+
4
+ Features
5
+ ========
6
+
7
+ * Fire Kernel#autoload at an entire directory
8
+ * Fire it again at a subdirectory, for namespace'd models
9
+
10
+
11
+ Motivation/Examples
12
+ ===================
13
+
14
+ I was using Ramaze as a web framework, and discovered that the standard Ramaze way of loading a directory of files is to slurp them all (with 'acquire'). I decided I'd rather use autoload, and not load things I'm not using. But I wasn't really looking forward to this:
15
+
16
+ autoload :User, 'model/user'
17
+ autoload :Clan, 'model/clan'
18
+ autoload :Item, 'model/item'
19
+
20
+ ...ad nauseum. So, the first feature is a shallow, directory-based autoload:
21
+
22
+ AutoLoader << 'model'
23
+
24
+ Of course, being a pedant, I like to namespace my models. I don't want to slurp the entire directory tree. Instead, you can do this:
25
+
26
+ class User < MyFavoriteORM::Model
27
+ include AutoLoader
28
+ ...
29
+ end
30
+
31
+ Now, all AutoLoaded paths will be searched for a subdirectory called 'user', and all files within will be autoloaded. Just as if you'd done:
32
+
33
+ User.autoload :Anonymous, 'model/user/anonymous'
34
+ User.autoload :Registered, 'model/user/registered'
35
+
36
+ Of course, there's no requirement that you have a base class, or anything of the sort. If you just want a namespace, you can always do:
37
+
38
+ module MyNamespace; include AutoLoader; end
39
+
40
+ And you're done.
41
+
42
+
43
+ Compatibility
44
+ =============
45
+
46
+ Currently, Merb's extlib and Rails' activesupport are supported. It should be trivial to interface with other libraries.
@@ -0,0 +1,105 @@
1
+ autoload :Set, 'set'
2
+ autoload :Pathname, 'pathname'
3
+
4
+ module AutoLoader
5
+
6
+ EXTENSIONS = %w{rb o}.map(&:freeze).freeze
7
+
8
+ # We need some sort of inflection library.
9
+ # Note: Sequel provides its own inflector, too...
10
+ # This should be done in a more extensible way.
11
+ def self.own_dependencies
12
+ require 'extlib/string'
13
+ rescue LoadError
14
+ begin
15
+ require 'active_support/inflector'
16
+ rescue LoadError
17
+ require 'rubygems'
18
+ gem 'activesupport'
19
+ require 'active_support/inflector'
20
+ end
21
+ end
22
+
23
+ # Find a method that the object responds to, and execute that.
24
+ # If no methods match, load dependencies and try again.
25
+ def self._try_methods object, *methods
26
+ method = methods.find {|m| object.respond_to? m}
27
+ if method
28
+ object.send method
29
+ else
30
+ nil
31
+ end
32
+ end
33
+ def self.try_methods object, *methods
34
+ self._try_methods(object, *methods) || (
35
+ self.own_dependencies
36
+ self._try_methods(object, *methods) || raise(NoMethodError, methods.first.to_s)
37
+ )
38
+ end
39
+
40
+ # Semi-agnostic inflections.
41
+ # Send patches, feel free to monkeypatch it, or
42
+ # define your own camelize/underscore methods.
43
+ def self.to_file_name string
44
+ self.try_methods string, :to_const_path, :camelize
45
+ end
46
+ def self.to_const_name string
47
+ self.try_methods string, :to_const_string, :underscore
48
+ end
49
+
50
+
51
+ def self.paths
52
+ @paths ||= Set.new
53
+ end
54
+
55
+ def self.push *args
56
+ args.each do
57
+ self << args
58
+ end
59
+ end
60
+
61
+ def self.<< path
62
+ unless self.paths.include? path
63
+ self.paths << path
64
+ unless $:.include? path
65
+ $: << path
66
+ end
67
+
68
+ self.update(:path => path)
69
+ end
70
+ end
71
+
72
+ def self.update(options)
73
+ if !options[:path]
74
+ self.paths.each {|p| self.update(options.merge(:path => p))}
75
+ else
76
+
77
+ path = Pathname.new options[:path]
78
+ parent = options[:parent]
79
+
80
+ glob_path = parent.nil? ? path : path.join(self.to_file_name parent.name)
81
+
82
+ EXTENSIONS.each do |ext|
83
+ Pathname.glob(glob_path.join("*.#{ext}").to_s).each do |file|
84
+ basename = file.basename(file.extname)
85
+
86
+ camelized = self.to_const_name basename.to_s
87
+ next unless camelized =~ /^[A-Z]\w*/
88
+
89
+ req_path = file.parent.relative_path_from(path).join(basename).to_s
90
+
91
+ if parent.nil?
92
+ Object.autoload camelized, req_path
93
+ else
94
+ parent.autoload camelized, req_path
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ # Some syntactic sugar
102
+ def self.included mod
103
+ self.update(:parent => mod)
104
+ end
105
+ end
metadata ADDED
@@ -0,0 +1,56 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: autoloader
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - David Masover
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-01-07 00:00:00 -06:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: ninja@slaphack.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - README
26
+ - lib/autoloader.rb
27
+ has_rdoc: true
28
+ homepage: http://github.com/masover/autoloader
29
+ licenses: []
30
+
31
+ post_install_message:
32
+ rdoc_options: []
33
+
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: "0"
41
+ version:
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ requirements: []
49
+
50
+ rubyforge_project:
51
+ rubygems_version: 1.3.5
52
+ signing_key:
53
+ specification_version: 3
54
+ summary: Crawl a directory at a time, adding files via Kernel#autoload
55
+ test_files: []
56
+