dyoder-autocode 0.9.3 → 0.9.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/lib/autocode.rb CHANGED
@@ -1,8 +1,10 @@
1
- require 'reloadable'
2
-
3
1
  module Autocode
2
+
3
+ def self.extended( mod )
4
+ included(mod)
5
+ end
4
6
 
5
- def self.extended( mod ) #:nodoc:
7
+ def self.included( mod )
6
8
 
7
9
  old = mod.method( :const_missing )
8
10
  mod.metaclass.class_eval do
@@ -23,6 +25,14 @@ module Autocode
23
25
  return self
24
26
  end
25
27
 
28
+ def autocreate_class( key = true, superclass = nil )
29
+ autocreate key, Class.new( superclass )
30
+ end
31
+
32
+ def autocreate_module( key = true )
33
+ autocreate key, Module.new
34
+ end
35
+
26
36
  def autoinit( key, &block )
27
37
  # See whether we're dealing with a namespaced constant,
28
38
  # The match groupings for, e.g. "X::Y::Z", would be
@@ -41,34 +51,55 @@ module Autocode
41
51
  return self
42
52
  end
43
53
 
44
- def autoload( key, options )
54
+ def autoload(key = true, options = {})
55
+ snake_case = lambda {|name| name.gsub(/([a-z\d])([A-Z])/){"#{$1}_#{$2}"}.tr("-", "_").downcase }
45
56
  # look for load_files in either a specified directory, or in the directory
46
57
  # with the snakecase name of the enclosing module
47
- directories = [options[:directories] || default_directory(self.name)].flatten
58
+ directories = [options[:directories] || snake_case.call(self.name.match( /^.*::([\w\d_]+)$/)[1])].flatten
48
59
  # create a lambda that looks for a file to load
49
60
  file_finder = lambda do |cname|
50
- filename = default_file_name(cname)
51
- dirname = directories.find do |dir|
52
- File.exist?(File.join(dir.to_s, filename))
53
- end
54
- dirname ? File.join(dirname.to_s, filename) : nil
61
+ filename = snake_case.call(cname.to_s << ".rb")
62
+ path = directories.map { |dir| File.join(dir.to_s, filename) }.find { |path| File.exist?( path ) }
55
63
  end
56
64
  # if no exemplar is given, assume Module.new
57
65
  @load_files ||= Hash.new
58
- @load_files[key] = [file_finder, options[:exemplar]]
66
+ @load_files[key] = [file_finder, options[:exemplar] || Module.new]
59
67
  return self
60
68
  end
61
69
 
62
- def autoload_class(key, superclass=nil, options={})
70
+ def autoload_class(key = true, superclass = nil, options = {})
63
71
  options[:exemplar] = Class.new(superclass)
64
72
  autoload key, options
65
73
  end
66
74
 
67
- def autoload_module(key, options={})
75
+ def autoload_module(key = true, options = {})
68
76
  options[:exemplar] = Module.new
69
77
  autoload key, options
70
78
  end
71
-
79
+
80
+ # Returns the list of constants that would be reloaded upon a call to reload.
81
+ def reloadable( *names )
82
+ ( @reloadable ||= [] ).concat(names)
83
+ return self
84
+ end
85
+
86
+ # Reloads all the constants that were loaded via autocode. Technically, all reload
87
+ # is doing is undefining them (by calling +remove_const+ on each in turn); they won't get
88
+ # reloaded until they are referenced.
89
+ def reload
90
+ @reloadable.each { |name| remove_const( name ) } if @reloadable
91
+ @reloadable = nil
92
+ return self
93
+ end
94
+
95
+ # Unloads all the constants that were loaded and removes all auto* definitions.
96
+ def unload
97
+ reload
98
+ @exemplars = @init_blocks = @load_files = nil
99
+ return self
100
+ end
101
+
102
+ private
72
103
 
73
104
  define_method :const_missing do | cname | #:nodoc:
74
105
  cname = cname.to_sym
@@ -97,16 +128,7 @@ module Autocode
97
128
  load(filename) if filename
98
129
  return object
99
130
  end
100
-
101
- def default_file_name(cname)
102
- ( cname.to_s.gsub(/([a-z\d])([A-Z\d])/){ "#{$1}_#{$2}"} << ".rb" ).downcase
103
- end
104
-
105
- def default_directory(module_name)
106
- m = self.name.match( /^.*::([\w\d_]+)$/)
107
- m[1].snake_case
108
- end
109
-
131
+
110
132
  end
111
133
  end
112
134
  end
data/test/autocreate.rb CHANGED
@@ -14,6 +14,10 @@ describe "A module where autocreate has been called" do
14
14
  end
15
15
  end
16
16
 
17
+ after do
18
+ Thingy.unload
19
+ end
20
+
17
21
  it "should autocreate some constants" do
18
22
  Thingy::Tom.peeps.should == true
19
23
  Thingy::Dick.peeps.should == false
@@ -33,6 +37,7 @@ describe "A module where autocreate has been called" do
33
37
  end
34
38
 
35
39
  Duffel::AnyThing.universal.should == true
40
+ Duffel.unload
36
41
  end
37
42
 
38
43
  end
data/test/autoinit.rb CHANGED
@@ -37,6 +37,13 @@ describe "thingy" do
37
37
  end
38
38
  end
39
39
 
40
+ after do
41
+ Thingy::Whatsit.unload
42
+ Thingy::Big::Bad.unload
43
+ Thingy::Big.unload
44
+ Thingy.unload
45
+ end
46
+
40
47
  it "fdfdsf" do
41
48
  Thingy::Whatsit.in_scope.should.be.true
42
49
  Thingy::Whatsit::Critter.outside_scope.should.be.true
data/test/autoload.rb CHANGED
@@ -10,15 +10,45 @@ describe "A module where autoload has been called" do
10
10
  autoload_module :Humbug, :directories => [File.join(File.dirname(__FILE__), "test_lib")]
11
11
  end
12
12
  end
13
+ module Waves
14
+ module TestLib
15
+ extend Autocode
16
+ autoload true, :exemplar => Module.new
17
+ end
18
+ end
19
+ module Whatever
20
+ module TestLib
21
+ extend Autocode
22
+ autoload
23
+ end
24
+ end
13
25
  end
14
26
 
27
+ after do
28
+ Thingy::Mabob.unload
29
+ Waves::TestLib.unload
30
+ Whatever::TestLib.unload
31
+ end
32
+
15
33
  it "should autoload where files match" do
16
34
  Thingy::Mabob::DooDad.should.respond_to :gizmo
17
35
  Thingy::Mabob::Humbug.should.respond_to :full_of_it?
18
36
  end
19
37
 
38
+ it "should not autoload where it matches a file but is out of scope" do
39
+ lambda { Thingy::Whatsit::Critter }.should.raise NameError
40
+ end
41
+
20
42
  it "should not autocreate those unmentioned and fileable" do
21
43
  lambda { Thingy::Mabob::MooCow }.should.raise NameError
22
44
  end
23
45
 
46
+ it "should autoload using default directories" do
47
+ Waves::TestLib::TheHelperModule.should.respond_to :help
48
+ end
49
+
50
+ it "should allow default options" do
51
+ Whatever::TestLib::TheOneAndOnly.should.respond_to :help
52
+ end
53
+
24
54
  end
data/test/helpers.rb CHANGED
@@ -1,8 +1,7 @@
1
- %w{ rubygems bacon}.each { |dep| require dep }
1
+ %w{ rubygems bacon metaid }.each { |dep| require dep }
2
2
  Bacon.extend Bacon::TestUnitOutput
3
3
  Bacon.summary_on_exit
4
4
 
5
- $:.unshift File.join(File.dirname(__FILE__) , "lib")
5
+ $:.unshift File.join(File.dirname(__FILE__) , "../lib")
6
6
  require 'autocode'
7
7
 
8
- # Dir.chdir(File.dirname(__FILE__))
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dyoder-autocode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Yoder
data/lib/reloadable.rb DELETED
@@ -1,30 +0,0 @@
1
- require 'rubygems'
2
- require 'metaid'
3
-
4
- # Reloadable simply makes it possible for a module's code to be reloaded. *Important*: Only code loaded via Autoload or Autocreate will be reloaded. Also, the module itself is not reloaded, only the modules and classes within it that were loaded via *Autocode*.
5
- #
6
- # To use Reloadable, simply extend a given module with Reloadable. This will add two methods to the module: reloadable and reload. These are described below.
7
-
8
- module Reloadable
9
-
10
- def self.extended( mod ) #:nodoc:
11
-
12
- mod.metaclass.class_eval do
13
-
14
- # Returns the list of constants that would be reloaded upon a call to reload.
15
- def reloadable( *names )
16
- ( @reloadable ||= [] ).concat(names)
17
- return self
18
- end
19
-
20
- # Reloads all the constants that were loaded via *Autocode*. Technically, all reload is doing is undefining them (by calling +remove_const+ on each in turn); they won't get reloaded until they are referenced.
21
- def reload
22
- ( @reloadable ||=[] ).each { |name| remove_const( name ) }
23
- @reloadable = []; return self
24
- end
25
-
26
- end
27
-
28
- end
29
-
30
- end