sweetloader 0.1.2 → 0.1.4

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.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