sweetloader 0.1.2 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.mdown CHANGED
@@ -1,6 +1,6 @@
1
1
  # Sweetloader
2
2
 
3
- A 'sweet' autoloader that can autoload your modules and classes more easily, by taking advantage of a standard directory structure approach for the placement of your classes and modules. You can also configure Sweetloader to override the defaults in various ways...
3
+ A 'sweet' autoloader designed to autoload your modules and classes more easily, by taking advantage of a standard directory structure approach for the placement of your classes and modules. You can also configure Sweetloader to override the defaults in various ways... and even have it use `require` instead of `autoload` :)
4
4
 
5
5
  ## Install
6
6
 
@@ -26,32 +26,52 @@ end
26
26
 
27
27
  Each of these modules are then expected to be in @catango/configuration.rb@ and similar relative to a load path.
28
28
 
29
- ## Configuration
29
+ ## AutoLoader Configuration
30
30
 
31
31
  The following global config vars are available in AutoLoader:
32
32
  * root
33
33
  * namespaces
34
+ * mode
35
+
36
+ ### Root
34
37
 
35
38
  Set a specific root which the dir will be calculated relative to, using root.
36
- Override namespace to directory auto-mapping using the namespaces hash.
37
39
 
38
40
  ```ruby
39
- AutoLoader.root = ''
41
+ AutoLoader.root = 'fixtures'
42
+ ```
43
+
44
+ Now the constant `::CanTango` will be resolved as `'fixtures/can_tango'`
45
+
46
+ ### Namespaces
47
+
48
+ Normally the constant CanTango will be translated to the dir `'can_tango'`, here we override this so it will instead be translated to `'cantango'`.
49
+
50
+ ```ruby
40
51
  AutoLoader.namespaces= {:CanTango => 'cantango', :Permithelper => 'permit_helper'}
41
52
  ```
42
53
 
43
- Normally the namespace/constant CanTango will be translated to the dir 'can_tango', here we override this so it will instead be translated to 'cantango'.
54
+ ### Modes
55
+
56
+ AutoLoader supports the following modes: `:autoload, :require`
57
+
58
+ The mode `:require` is used to execute require statements directly. The `:autoload` mode is used to do autoloading.
59
+ Note that autoloading is not stable in multi-threaded environments and will likely be deprecated in later version of Ruby.
60
+ However autoloading does perform lazy loading and can be advantageous when you want to speed up initial load time and don't run in a multi-threaded environment.
44
61
 
45
- You can also specify these options directly as an option hash on the `#autoload_modules` call
62
+ ## autoload_modules Configuration
63
+
64
+ You can also specify the AutoLoader options directly as an option hash on the `#autoload_modules` call:
46
65
 
47
66
  ```ruby
48
- autoload_modules :Configuration, :Factory, :Permit, :root => 'helpers'
49
- autoload_modules :Configuration, :Factory, :Permit, :ns => {:CanTango => 'cantango'}
67
+ autoload_modules :Configuration, :mode => :require
68
+ autoload_modules :Configuration, :Factory, :root => 'helpers'
69
+ autoload_modules :Configuration, :Factory, :Permit, :ns => {:CanTango => 'cantango'} # or use :namespaces
50
70
  ```
51
71
 
52
72
  ## Mutate path option
53
73
 
54
- Can be used to execute more general substitution logic on the generated file path
74
+ This option is only available for `autoload_modules`. It can be used to execute more general substitution logic on the generated file path:
55
75
 
56
76
  ```ruby
57
77
  autoload_modules :Configuration, :Factory, :Permit, :mutate_path => Proc.new {|path| path.sub(/(ies)/, 'y') }
@@ -59,6 +79,8 @@ Can be used to execute more general substitution logic on the generated file pat
59
79
 
60
80
  ## Scopes
61
81
 
82
+ A Scope allows options to be specified that are effective on all `autoload_modules` statements within the scope.
83
+
62
84
  ```ruby
63
85
  module AutoloadModules
64
86
  module Configuration
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.1.4
data/lib/sweetloader.rb CHANGED
@@ -2,6 +2,8 @@ require 'active_support/core_ext/string/inflections'
2
2
 
3
3
 
4
4
  module SweetLoader
5
+ class InvalidAutoloadMode < StandardError; end
6
+
5
7
  def include_and_extend(the_module, options={})
6
8
  options[:instance_methods] ||= :InstanceMethods
7
9
  options[:class_methods] ||= :ClassMethods
@@ -25,15 +27,33 @@ module SweetLoader
25
27
  the_module = send(:the_module) if respond_to? :the_module
26
28
  the_module ||= self
27
29
 
30
+ mode = alm_options[:mode] if AutoLoader.valid_mode? alm_options[:mode]
31
+ mode ||= AutoLoader.mode
32
+
33
+ logic = alm_options[:proc] if alm_options[:proc].respond_to? :call
34
+ logic ||= mode_logic mode
35
+
28
36
  # Here also could be adding of the file in top of load_paths like: $:.unshift File.dirname(__FILE__)
29
37
  # It is very useful for situations of having not load_paths built Rails or Gems way.
30
- args.each do |req_name|
31
- ruby_file = req_name.to_s.underscore
38
+ args.each do |module_name|
39
+ ruby_file = module_name.to_s.underscore
40
+ module_name = module_name.to_s.camelize.to_sym
32
41
  require_file = AutoLoader.translate("#{from}/#{ruby_file}", alm_options)
33
- the_module.send :autoload, req_name, require_file
42
+ logic.call(the_module, module_name, require_file)
34
43
  end
35
44
  end
36
45
  alias_method :autoload_module, :autoload_modules
46
+
47
+ def mode_logic mode
48
+ case mode
49
+ when :autoload
50
+ Proc.new { |the_module, module_name, require_file| the_module.send :autoload, module_name, require_file }
51
+ when :require
52
+ Proc.new {|the_module, module_name, require_file| require require_file }
53
+ else
54
+ raise InvalidAutoloadMode, "Not a valid Autloader mode: #{AutoLoader.mode}, must be one of: #{AutoLoader.valid_mode}"
55
+ end
56
+ end
37
57
 
38
58
  def autoload_scope options = {}, &block
39
59
  if block_given?
@@ -41,132 +61,12 @@ module SweetLoader
41
61
  end
42
62
  end
43
63
  end
44
-
45
- module SweetLoader
46
- class Scope
47
- include SweetLoader
48
-
49
- attr_reader :autoload_options, :the_module
50
-
51
- def initialize the_module, options = {}
52
- @the_module = the_module
53
- @autoload_options = options
54
- end
55
-
56
- def name
57
- the_module.name
58
- end
59
- end
60
- end
61
64
 
62
65
  class Module
63
66
  include SweetLoader
64
67
  end
65
68
 
66
- module AutoLoader
67
- @@root = ''
68
- @@namespaces = {}
69
-
70
- def self.root
71
- @@root
72
- end
73
-
74
- def self.namespaces
75
- @@namespaces
76
- end
77
-
78
- def self.root= root
79
- @@root = root
80
- end
81
-
82
- def self.namespaces= namespaces
83
- @@namespaces = namespaces
84
- end
85
-
86
- def self.translate name, options = {}
87
- names = name.split('/')
88
- ns = namespaces.merge(options[:namespaces] || options[:ns] || {})
89
- names.map do |name|
90
- clazz_name = name.to_s.camelize
91
- folder = ns[clazz_name.to_sym] ? ns[clazz_name.to_sym] : name
92
- folder.sub /\/$/, ''
93
- end.join('/')
94
- end
95
- end
96
-
97
- module ClassExt
98
- class ModuleNotFoundError < StandardError; end
99
- class ClassNotFoundError < StandardError; end
100
-
101
- def get_module name
102
- # Module.const_get(name)
103
- name.to_s.camelize.constantize
104
- rescue
105
- nil
106
- end
69
+ require 'sweetloader/scope'
70
+ require 'sweetloader/auto_loader'
71
+ require 'sweetloader/class_ext'
107
72
 
108
- def is_class?(clazz)
109
- clazz.is_a?(Class) && (clazz.respond_to? :new)
110
- end
111
-
112
- def is_module?(clazz)
113
- clazz.is_a?(Module) && !(clazz.respond_to? :new)
114
- end
115
-
116
- def class_exists?(name)
117
- is_class? get_module(name)
118
- rescue
119
- return false
120
- end
121
-
122
- def module_exists?(name)
123
- is_module? get_module(name)
124
- rescue NameError
125
- return false
126
- end
127
-
128
- def try_class name
129
- return name if name.kind_of?(Class)
130
- found = get_module(name) if name.is_a?(String) || name.is_a?(Symbol)
131
- return found if found.is_a?(Class)
132
- rescue
133
- false
134
- end
135
-
136
- def try_module name
137
- return name if name.kind_of?(Module)
138
- found = get_module(name.to_s) if name.is_a?(String) || name.is_a?(Symbol)
139
- return found if found.is_a?(Module)
140
- rescue
141
- false
142
- end
143
-
144
- def try_module_only name
145
- return name if is_module?(name)
146
- found = get_module(name) if name.is_a?(String) || name.is_a?(Symbol)
147
- return found if is_module?(found)
148
- rescue
149
- false
150
- end
151
-
152
-
153
- def find_first_class *names
154
- classes = names.flatten.compact.uniq.inject([]) do |res, class_name|
155
- found_class = try_class(class_name.to_s.camelize)
156
- res << found_class if found_class
157
- res
158
- end
159
- raise ClassNotFoundError, "Not one Class for any of: #{names} is currently loaded" if classes.empty?
160
- classes.first
161
- end
162
-
163
- def find_first_module *names
164
- modules = names.flatten.compact.uniq.inject([]) do |res, class_name|
165
- found_class = try_module(class_name.to_s.camelize)
166
- res << found_class if found_class
167
- res
168
- end
169
- raise ModuleNotFoundError, "Not one Module for any of: #{names} is currently loaded" if modules.empty?
170
- modules.first
171
- end
172
- end
@@ -0,0 +1,54 @@
1
+ module AutoLoader
2
+ module ClassMethods
3
+ attr_writer :default_mode
4
+
5
+ def root
6
+ @root ||= ''
7
+ end
8
+
9
+ def root= root
10
+ raise ArgumentError, "Must be a String, was: #{root}" if !root.kind_of?(String)
11
+ @root = root
12
+ end
13
+
14
+ def namespaces
15
+ @namespaces ||= {}
16
+ end
17
+
18
+ def namespaces= namespaces
19
+ raise ArgumentError, "Must be a Hash, was: #{namespaces}" if !namespaces.kind_of?(Hash)
20
+ @namespaces = namespaces
21
+ end
22
+
23
+ def mode
24
+ @mode || default_mode
25
+ end
26
+
27
+ def mode= mode
28
+ @mode = mode if valid_mode? mode
29
+ end
30
+
31
+ def valid_mode? mode
32
+ valid_modes.include? mode
33
+ end
34
+
35
+ def valid_modes
36
+ [:autoload, :require]
37
+ end
38
+
39
+ def default_mode
40
+ valid_modes.first
41
+ end
42
+ end
43
+ extend ClassMethods
44
+
45
+ def self.translate name, options = {}
46
+ names = name.split('/')
47
+ ns = namespaces.merge(options[:namespaces] || options[:ns] || {})
48
+ names.map do |name|
49
+ clazz_name = name.to_s.camelize
50
+ folder = ns[clazz_name.to_sym] ? ns[clazz_name.to_sym] : name
51
+ folder.sub /\/$/, ''
52
+ end.join('/')
53
+ end
54
+ end
@@ -0,0 +1,76 @@
1
+ module ClassExt
2
+ class ModuleNotFoundError < StandardError; end
3
+ class ClassNotFoundError < StandardError; end
4
+
5
+ def get_module name
6
+ # Module.const_get(name)
7
+ name.to_s.camelize.constantize
8
+ rescue
9
+ nil
10
+ end
11
+
12
+ def is_class?(clazz)
13
+ clazz.is_a?(Class) && (clazz.respond_to? :new)
14
+ end
15
+
16
+ def is_module?(clazz)
17
+ clazz.is_a?(Module) && !(clazz.respond_to? :new)
18
+ end
19
+
20
+ def class_exists?(name)
21
+ is_class? get_module(name)
22
+ rescue
23
+ return false
24
+ end
25
+
26
+ def module_exists?(name)
27
+ is_module? get_module(name)
28
+ rescue NameError
29
+ return false
30
+ end
31
+
32
+ def try_class name
33
+ return name if name.kind_of?(Class)
34
+ found = get_module(name) if name.is_a?(String) || name.is_a?(Symbol)
35
+ return found if found.is_a?(Class)
36
+ rescue
37
+ false
38
+ end
39
+
40
+ def try_module name
41
+ return name if name.kind_of?(Module)
42
+ found = get_module(name.to_s) if name.is_a?(String) || name.is_a?(Symbol)
43
+ return found if found.is_a?(Module)
44
+ rescue
45
+ false
46
+ end
47
+
48
+ def try_module_only name
49
+ return name if is_module?(name)
50
+ found = get_module(name) if name.is_a?(String) || name.is_a?(Symbol)
51
+ return found if is_module?(found)
52
+ rescue
53
+ false
54
+ end
55
+
56
+
57
+ def find_first_class *names
58
+ classes = names.flatten.compact.uniq.inject([]) do |res, class_name|
59
+ found_class = try_class(class_name.to_s.camelize)
60
+ res << found_class if found_class
61
+ res
62
+ end
63
+ raise ClassNotFoundError, "Not one Class for any of: #{names} is currently loaded" if classes.empty?
64
+ classes.first
65
+ end
66
+
67
+ def find_first_module *names
68
+ modules = names.flatten.compact.uniq.inject([]) do |res, class_name|
69
+ found_class = try_module(class_name.to_s.camelize)
70
+ res << found_class if found_class
71
+ res
72
+ end
73
+ raise ModuleNotFoundError, "Not one Module for any of: #{names} is currently loaded" if modules.empty?
74
+ modules.first
75
+ end
76
+ end
@@ -0,0 +1,16 @@
1
+ module SweetLoader
2
+ class Scope
3
+ include SweetLoader
4
+
5
+ attr_reader :autoload_options, :the_module
6
+
7
+ def initialize the_module, options = {}
8
+ @the_module = the_module
9
+ @autoload_options = options
10
+ end
11
+
12
+ def name
13
+ the_module.name
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,4 @@
1
+ module AutoloadModules
2
+ module Procedure
3
+ end
4
+ end
@@ -7,6 +7,10 @@ module AutoloadModules
7
7
  autoload_modules :Abc
8
8
  autoload_modules :Xyz
9
9
  end
10
+
11
+ autoload_scope :proc => Proc.new {|the_module, module_name, require_file| require require_file } do
12
+ autoload_modules :Procedure
13
+ end
10
14
  end
11
15
 
12
16
  module AutoloadModules
@@ -22,5 +22,11 @@ describe 'Sweetloader options' do
22
22
  lambda { AutoloadModules::Configuration::Editor }.should_not raise_error
23
23
  end
24
24
  end
25
+
26
+ describe "#autoload_scope with :proc option" do
27
+ specify do
28
+ lambda { AutoloadModules::Procedure }.should_not raise_error
29
+ end
30
+ end
25
31
  end
26
32
  end
data/sweetloader.gemspec CHANGED
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{sweetloader}
8
- s.version = "0.1.2"
7
+ s.name = "sweetloader"
8
+ s.version = "0.1.4"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = [%q{Kristian Mandrup}]
12
- s.date = %q{2011-11-28}
13
- s.description = %q{sweet autoloading using file structure conventions while allowing configuration overrides for special cases}
14
- s.email = %q{kmandrup@gmail.com}
11
+ s.authors = ["Kristian Mandrup"]
12
+ s.date = "2011-11-29"
13
+ s.description = "sweet autoloading using file structure conventions while allowing configuration overrides for special cases"
14
+ s.email = "kmandrup@gmail.com"
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE.txt",
17
17
  "README.mdown"
@@ -25,11 +25,15 @@ Gem::Specification.new do |s|
25
25
  "Rakefile",
26
26
  "VERSION",
27
27
  "lib/sweetloader.rb",
28
+ "lib/sweetloader/auto_loader.rb",
29
+ "lib/sweetloader/class_ext.rb",
30
+ "lib/sweetloader/scope.rb",
28
31
  "spec/auto_load_blank_root.rb",
29
32
  "spec/autoload_blank_root.rb",
30
33
  "spec/autoload_blank_root/hello.rb",
31
34
  "spec/autoload_blank_root/sailor.rb",
32
35
  "spec/autoload_modules/configuration/editor.rb",
36
+ "spec/autoload_modules/procedure.rb",
33
37
  "spec/class_ext_spec.rb",
34
38
  "spec/fixtures/autoload_modules.rb",
35
39
  "spec/fixtures/autoload_modules/subdir/first.rb",
@@ -53,11 +57,11 @@ Gem::Specification.new do |s|
53
57
  "spec/sweetloader/sweetloader_spec.rb",
54
58
  "sweetloader.gemspec"
55
59
  ]
56
- s.homepage = %q{http://github.com/kristianmandrup/sweetloader}
57
- s.licenses = [%q{MIT}]
58
- s.require_paths = [%q{lib}]
59
- s.rubygems_version = %q{1.8.6}
60
- s.summary = %q{sweetens up autoloading using file structure conventions}
60
+ s.homepage = "http://github.com/kristianmandrup/sweetloader"
61
+ s.licenses = ["MIT"]
62
+ s.require_paths = ["lib"]
63
+ s.rubygems_version = "1.8.10"
64
+ s.summary = "sweetens up autoloading using file structure conventions"
61
65
 
62
66
  if s.respond_to? :specification_version then
63
67
  s.specification_version = 3
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sweetloader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-28 00:00:00.000000000Z
12
+ date: 2011-11-29 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
- requirement: &70350317938260 !ruby/object:Gem::Requirement
16
+ requirement: &899195900 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 3.0.1
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70350317938260
24
+ version_requirements: *899195900
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: i18n
27
- requirement: &70350317937740 !ruby/object:Gem::Requirement
27
+ requirement: &899195210 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70350317937740
35
+ version_requirements: *899195210
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec
38
- requirement: &70350317937200 !ruby/object:Gem::Requirement
38
+ requirement: &899194770 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 2.5.0
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70350317937200
46
+ version_requirements: *899194770
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
- requirement: &70350317936580 !ruby/object:Gem::Requirement
49
+ requirement: &899194410 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.1.rc
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70350317936580
57
+ version_requirements: *899194410
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: jeweler
60
- requirement: &70350317933820 !ruby/object:Gem::Requirement
60
+ requirement: &899194080 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.6.4
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70350317933820
68
+ version_requirements: *899194080
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rcov
71
- requirement: &70350317933120 !ruby/object:Gem::Requirement
71
+ requirement: &899193050 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,7 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70350317933120
79
+ version_requirements: *899193050
80
80
  description: sweet autoloading using file structure conventions while allowing configuration
81
81
  overrides for special cases
82
82
  email: kmandrup@gmail.com
@@ -94,11 +94,15 @@ files:
94
94
  - Rakefile
95
95
  - VERSION
96
96
  - lib/sweetloader.rb
97
+ - lib/sweetloader/auto_loader.rb
98
+ - lib/sweetloader/class_ext.rb
99
+ - lib/sweetloader/scope.rb
97
100
  - spec/auto_load_blank_root.rb
98
101
  - spec/autoload_blank_root.rb
99
102
  - spec/autoload_blank_root/hello.rb
100
103
  - spec/autoload_blank_root/sailor.rb
101
104
  - spec/autoload_modules/configuration/editor.rb
105
+ - spec/autoload_modules/procedure.rb
102
106
  - spec/class_ext_spec.rb
103
107
  - spec/fixtures/autoload_modules.rb
104
108
  - spec/fixtures/autoload_modules/subdir/first.rb
@@ -136,7 +140,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
136
140
  version: '0'
137
141
  segments:
138
142
  - 0
139
- hash: 648157612907280241
143
+ hash: -951501357
140
144
  required_rubygems_version: !ruby/object:Gem::Requirement
141
145
  none: false
142
146
  requirements:
@@ -145,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
149
  version: '0'
146
150
  requirements: []
147
151
  rubyforge_project:
148
- rubygems_version: 1.8.6
152
+ rubygems_version: 1.8.10
149
153
  signing_key:
150
154
  specification_version: 3
151
155
  summary: sweetens up autoloading using file structure conventions