masover-autoloader 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. data/README +46 -0
  2. data/lib/autoloader.rb +105 -0
  3. metadata +54 -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.
data/lib/autoloader.rb ADDED
@@ -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,54 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: masover-autoloader
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
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 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: dave@3mix.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - README
26
+ - lib/autoloader.rb
27
+ has_rdoc: false
28
+ homepage:
29
+ post_install_message:
30
+ rdoc_options: []
31
+
32
+ require_paths:
33
+ - lib
34
+ required_ruby_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: "0"
39
+ version:
40
+ required_rubygems_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: "0"
45
+ version:
46
+ requirements: []
47
+
48
+ rubyforge_project:
49
+ rubygems_version: 1.2.0
50
+ signing_key:
51
+ specification_version: 2
52
+ summary: Crawl a directory at a time, adding files via Kernel#autoload
53
+ test_files: []
54
+