dyoder-autocode 0.9.8 → 0.9.9
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 +43 -55
- data/test/auto_create.rb +1 -1
- data/test/auto_eval.rb +5 -5
- data/test/auto_load.rb +12 -13
- metadata +2 -2
data/lib/autocode.rb
CHANGED
@@ -6,56 +6,55 @@ module AutoCode
|
|
6
6
|
cname.gsub(/(_)(\w)/) { $2.upcase }.gsub(/^([a-z])/) { $1.upcase }.intern
|
7
7
|
end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
def call(cname)
|
12
|
-
filename = Loader.snake_case( cname ) << '.rb'
|
13
|
-
if @directories.nil?
|
14
|
-
Kernel.load( filename )
|
15
|
-
else
|
16
|
-
path = @directories.map { |dir| File.join( dir.to_s, filename ) }.find { |path| File.exist?( path ) }
|
17
|
-
Kernel.load( path ) rescue nil unless path.nil?
|
18
|
-
end
|
19
|
-
end
|
20
|
-
def Loader.snake_case(cname)
|
21
|
-
cname.to_s.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
|
22
|
-
end
|
9
|
+
def AutoCode.snake_case( cname )
|
10
|
+
cname.to_s.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase
|
23
11
|
end
|
24
|
-
|
25
|
-
|
26
|
-
def initialize( options, &block )
|
27
|
-
@exemplar = (options[:exemplar]||Module.new).clone; @block = block
|
28
|
-
end
|
29
|
-
def call ; @exemplar.module_eval( &@block ) if @block ; @exemplar ; end
|
30
|
-
end
|
31
|
-
|
32
|
-
class Initializer
|
33
|
-
def initialize( &block ) ;@block = block ; end
|
34
|
-
def call( mod ) ; mod.module_eval( &@block ) ; end
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.extended( mod ) ; included(mod) ; end
|
12
|
+
|
13
|
+
def self.extended( mod ) ; included( mod ) ; end
|
38
14
|
|
39
15
|
def self.included( mod )
|
40
16
|
|
41
17
|
mod.instance_eval do
|
42
18
|
|
19
|
+
# First make sure we haven't already done this once
|
20
|
+
return unless @autocode.nil?
|
21
|
+
|
43
22
|
# Initialize bookkeeping variables needed by AutoCode
|
44
|
-
@
|
23
|
+
@autocode = {
|
24
|
+
:constructors => Hash.new { |h,k| h[k] = [] },
|
25
|
+
:initializers => Hash.new { |h,k| h[k] = [] },
|
26
|
+
:loaded => []
|
27
|
+
}
|
45
28
|
|
46
29
|
# Adds an auto_create block for the given key using the given exemplar if provided
|
47
30
|
def auto_create( key = true, options = {}, &block )
|
48
|
-
@
|
31
|
+
@autocode[:constructors][ AutoCode.normalize( key ) ] << lambda do | cname |
|
32
|
+
exemplar = ( options[:exemplar] || Module.new ).clone
|
33
|
+
exemplar.module_eval( &block ) if block
|
34
|
+
const_set( cname, exemplar )
|
35
|
+
end
|
49
36
|
end
|
50
37
|
|
51
38
|
# Adds an auto_load block for the given key and directories
|
52
39
|
def auto_load( key = true, options = {} )
|
53
|
-
@
|
40
|
+
@autocode[:constructors][ AutoCode.normalize( key ) ] << lambda do | cname |
|
41
|
+
filename = AutoCode.snake_case( cname ) << '.rb'
|
42
|
+
if options[:directories].nil?
|
43
|
+
Kernel.load( filename ) if File.exist?( filename )
|
44
|
+
else
|
45
|
+
path = options[:directories].
|
46
|
+
map { |dir| File.join( dir.to_s, filename ) }.
|
47
|
+
find { |path| File.exist?( path ) }
|
48
|
+
Kernel.load( path ) unless path.nil?
|
49
|
+
end
|
50
|
+
end
|
54
51
|
end
|
55
52
|
|
56
53
|
# Adds an arbitrary initializer block for the given key
|
57
54
|
def auto_eval( key, &block )
|
58
|
-
@initializers[ AutoCode.normalize( key ) ] <<
|
55
|
+
@autocode[:initializers][ AutoCode.normalize( key ) ] << lambda do | mod |
|
56
|
+
mod.module_eval( &block )
|
57
|
+
end
|
59
58
|
end
|
60
59
|
|
61
60
|
# Convenience method for auto_create.
|
@@ -68,37 +67,26 @@ module AutoCode
|
|
68
67
|
auto_create( key,{ :exemplar => Module.new }, &block )
|
69
68
|
end
|
70
69
|
|
71
|
-
# Reloading stuff ...
|
72
|
-
|
73
70
|
# Returns the list of constants that would be reloaded upon a call to reload.
|
74
|
-
def reloadable
|
71
|
+
def reloadable ; @autocode[:loaded] ; end
|
75
72
|
|
76
|
-
# Reloads all the constants that were loaded via auto_code.
|
77
|
-
|
78
|
-
# reloaded until they are referenced.
|
79
|
-
def reload ; @reloadable.each { |name| remove_const( name ) } ; @reloadable = [] ; self; end
|
80
|
-
|
81
|
-
# Unloads all the constants that were loaded and removes all auto* definitions.
|
82
|
-
def unload ; reload ; @initializers = Hash.new { |h,k| h[k] = [] } ; self ; end
|
73
|
+
# Reloads (via #remove_const) all the constants that were loaded via auto_code.
|
74
|
+
def reload ; @autocode[:loaded].each { |name| remove_const( name ) } ; @autocode[:loaded] = [] ; end
|
83
75
|
|
84
76
|
private
|
85
77
|
|
86
78
|
old = method( :const_missing )
|
87
79
|
(class << self ; self ; end ).instance_eval do
|
88
|
-
define_method :const_missing do | cname |
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
initializer.call( const_get( cname ) ) if const_defined?( cname )
|
96
|
-
end
|
97
|
-
end
|
98
|
-
return old.call(cname) unless const_defined?( cname )
|
99
|
-
@reloadable << cname ; const_get( cname )
|
80
|
+
define_method( :const_missing ) do | cname |
|
81
|
+
constructors = @autocode[:constructors][true] + @autocode[:constructors][cname]
|
82
|
+
constructors.pop.call( cname ) until ( const_defined?( cname ) or constructors.empty? )
|
83
|
+
return old.call( cname ) unless const_defined?( cname )
|
84
|
+
initializers = @autocode[:initializers][true] + @autocode[:initializers][cname]
|
85
|
+
mod = const_get( cname ) ; initializers.pop.call( mod ) until initializers.empty?
|
86
|
+
@autocode[:loaded] << cname ; const_get( cname )
|
100
87
|
end
|
101
88
|
end
|
102
89
|
end
|
103
90
|
end
|
104
|
-
end
|
91
|
+
end
|
92
|
+
Autocode = AutoCode
|
data/test/auto_create.rb
CHANGED
@@ -3,7 +3,7 @@ require File.join(File.dirname(__FILE__), 'helpers.rb')
|
|
3
3
|
describe "auto_create should" do
|
4
4
|
|
5
5
|
before do
|
6
|
-
|
6
|
+
Object.instance_eval { remove_const(:A) if const_defined?(:A) }
|
7
7
|
module A
|
8
8
|
include AutoCode
|
9
9
|
auto_create_module :B do
|
data/test/auto_eval.rb
CHANGED
@@ -3,7 +3,7 @@ require File.join(File.dirname(__FILE__), 'helpers.rb')
|
|
3
3
|
describe "auto_eval should" do
|
4
4
|
|
5
5
|
before do
|
6
|
-
|
6
|
+
Object.instance_eval { remove_const(:A) if const_defined?(:A) }
|
7
7
|
module A
|
8
8
|
include AutoCode
|
9
9
|
auto_create_module :B
|
@@ -14,8 +14,8 @@ describe "auto_eval should" do
|
|
14
14
|
end
|
15
15
|
A.auto_eval :B do
|
16
16
|
include AutoCode
|
17
|
-
auto_eval :
|
18
|
-
|
17
|
+
auto_eval :C do
|
18
|
+
self::D = true
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -24,8 +24,8 @@ describe "auto_eval should" do
|
|
24
24
|
A::B::C.class.should == Class
|
25
25
|
end
|
26
26
|
|
27
|
-
specify "
|
28
|
-
A::B::
|
27
|
+
specify "allow you to define nested auto_eval declarations" do
|
28
|
+
A::B::C::D.should == true
|
29
29
|
end
|
30
30
|
|
31
31
|
end
|
data/test/auto_load.rb
CHANGED
@@ -5,8 +5,8 @@ require 'extensions/io'
|
|
5
5
|
describe "auto_load should" do
|
6
6
|
|
7
7
|
before do
|
8
|
-
|
9
|
-
FileUtils.mkdir('tmp')
|
8
|
+
Object.instance_eval { remove_const(:A) if const_defined?(:A) }
|
9
|
+
FileUtils.mkdir('tmp') rescue nil
|
10
10
|
@path = File.join( 'tmp', 'b.rb' )
|
11
11
|
content =<<-EOF
|
12
12
|
module A
|
@@ -19,7 +19,6 @@ describe "auto_load should" do
|
|
19
19
|
include AutoCode
|
20
20
|
auto_create_class :B
|
21
21
|
auto_load :B, :directories => ['tmp']
|
22
|
-
auto_create_class :B
|
23
22
|
end
|
24
23
|
|
25
24
|
end
|
@@ -33,20 +32,20 @@ describe "auto_load should" do
|
|
33
32
|
A::B.class.should == Module
|
34
33
|
end
|
35
34
|
|
35
|
+
specify "should implement LIFO semantics" do
|
36
|
+
A::B.class.should == Module
|
37
|
+
end
|
38
|
+
|
36
39
|
specify "should raise a NameError if a const doesn't match" do
|
37
40
|
lambda{ A::C }.should.raise NameError
|
38
41
|
end
|
39
|
-
|
40
|
-
specify "always take precedence over auto_create" do
|
41
|
-
A::B.class.should == Module
|
42
|
-
end
|
43
|
-
|
42
|
+
|
44
43
|
specify "snake case the constant name which is used to map a constant to a filename" do
|
45
|
-
AutoCode
|
46
|
-
AutoCode
|
47
|
-
AutoCode
|
48
|
-
AutoCode
|
49
|
-
AutoCode
|
44
|
+
AutoCode.snake_case(:Post).should == "post"
|
45
|
+
AutoCode.snake_case(:GitHub).should == "git_hub"
|
46
|
+
AutoCode.snake_case(:GITRepository).should == "git_repository"
|
47
|
+
AutoCode.snake_case(:Git42Repository).should == "git42_repository"
|
48
|
+
AutoCode.snake_case(:GIT42Repository).should == "git42_repository"
|
50
49
|
end
|
51
50
|
|
52
51
|
end
|
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.
|
4
|
+
version: 0.9.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan Yoder
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-05-
|
12
|
+
date: 2008-05-15 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|