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.
- data/README +46 -0
- data/lib/autoloader.rb +105 -0
- 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
|
+
|