autocode 0.9.3 → 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,92 @@
1
- require 'autocreate'
2
- require 'autoload'
3
- require 'reloadable'
1
+ module AutoCode
2
+
3
+ # always make sure we have a camel-cased symbol
4
+ def AutoCode.normalize( cname )
5
+ return cname unless cname.is_a? String
6
+ cname.gsub(/(_)(\w)/) { $2.upcase }.gsub(/^([a-z])/) { $1.upcase }.intern
7
+ end
8
+
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
11
+ end
12
+
13
+ def self.extended( mod ) ; included( mod ) ; end
14
+
15
+ def self.included( mod )
16
+
17
+ mod.instance_eval do
18
+
19
+ # First make sure we haven't already done this once
20
+ return unless @autocode.nil?
21
+
22
+ # Initialize bookkeeping variables needed by AutoCode
23
+ @autocode = {
24
+ :constructors => Hash.new { |h,k| h[k] = [] },
25
+ :initializers => Hash.new { |h,k| h[k] = [] },
26
+ :loaded => []
27
+ }
28
+
29
+ # Adds an auto_create block for the given key using the given exemplar if provided
30
+ def auto_create( key = true, options = {}, &block )
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
36
+ end
37
+
38
+ # Adds an auto_load block for the given key and directories
39
+ def auto_load( key = true, options = {} )
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
51
+ end
52
+
53
+ # Adds an arbitrary initializer block for the given key
54
+ def auto_eval( key, &block )
55
+ @autocode[:initializers][ AutoCode.normalize( key ) ] << lambda do | mod |
56
+ mod.module_eval( &block )
57
+ end
58
+ end
59
+
60
+ # Convenience method for auto_create.
61
+ def auto_create_class( key = true, superclass = Object, &block )
62
+ auto_create( key,{ :exemplar => Class.new( superclass ) }, &block )
63
+ end
64
+
65
+ # Convenience method for auto_create.
66
+ def auto_create_module( key = true, &block )
67
+ auto_create( key,{ :exemplar => Module.new }, &block )
68
+ end
69
+
70
+ # Returns the list of constants that would be reloaded upon a call to reload.
71
+ def reloadable ; @autocode[:loaded] ; end
72
+
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
75
+
76
+ private
77
+
78
+ old = method( :const_missing )
79
+ (class << self ; self ; end ).instance_eval do
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 )
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ Autocode = AutoCode
@@ -0,0 +1,28 @@
1
+ require File.join(File.dirname(__FILE__), 'helpers.rb')
2
+
3
+ describe "auto_create should" do
4
+
5
+ before do
6
+ Object.instance_eval { remove_const(:A) if const_defined?(:A) }
7
+ module A
8
+ include AutoCode
9
+ auto_create_module :B do
10
+ include AutoCode
11
+ auto_create_class
12
+ end
13
+ end
14
+ end
15
+
16
+ specify "allow you create and initialize a given const name" do
17
+ A::B.class.should == Module
18
+ end
19
+
20
+ specify "allow you create and initialize const using a wildcard" do
21
+ A::B::C.class.should === Class
22
+ end
23
+
24
+ specify "should raise a NameError if a const doesn't match" do
25
+ lambda{ A::C }.should.raise NameError
26
+ end
27
+
28
+ end
@@ -0,0 +1,31 @@
1
+ require File.join(File.dirname(__FILE__), 'helpers.rb')
2
+
3
+ describe "auto_eval should" do
4
+
5
+ before do
6
+ Object.instance_eval { remove_const(:A) if const_defined?(:A) }
7
+ module A
8
+ include AutoCode
9
+ auto_create_module :B
10
+ end
11
+ A.auto_eval :B do
12
+ include AutoCode
13
+ auto_create_class
14
+ end
15
+ A.auto_eval :B do
16
+ include AutoCode
17
+ auto_eval :C do
18
+ self::D = true
19
+ end
20
+ end
21
+ end
22
+
23
+ specify "allow you to run blocks after an object is first created" do
24
+ A::B::C.class.should == Class
25
+ end
26
+
27
+ specify "allow you to define nested auto_eval declarations" do
28
+ A::B::C::D.should == true
29
+ end
30
+
31
+ end
@@ -0,0 +1,51 @@
1
+ require File.join(File.dirname(__FILE__), 'helpers.rb')
2
+ require 'extensions/io'
3
+
4
+
5
+ describe "auto_load should" do
6
+
7
+ before do
8
+ Object.instance_eval { remove_const(:A) if const_defined?(:A) }
9
+ FileUtils.mkdir('tmp') rescue nil
10
+ @path = File.join( 'tmp', 'b.rb' )
11
+ content =<<-EOF
12
+ module A
13
+ module B
14
+ end
15
+ end
16
+ EOF
17
+ File.write( @path, content )
18
+ module A
19
+ include AutoCode
20
+ auto_create_class :B
21
+ auto_load :B, :directories => ['tmp']
22
+ end
23
+
24
+ end
25
+
26
+ after do
27
+ FileUtils.rm( File.join( @path ) )
28
+ FileUtils.rmdir( 'tmp' )
29
+ end
30
+
31
+ specify "allow you to load a file to define a const" do
32
+ A::B.class.should == Module
33
+ end
34
+
35
+ specify "should implement LIFO semantics" do
36
+ A::B.class.should == Module
37
+ end
38
+
39
+ specify "should raise a NameError if a const doesn't match" do
40
+ lambda{ A::C }.should.raise NameError
41
+ end
42
+
43
+ specify "snake case the constant name which is used to map a constant to a filename" do
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"
49
+ end
50
+
51
+ end
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ %w{ bacon metaid }.each { |dep| require dep }
3
+ # Bacon.extend Bacon::TestUnitOutput
4
+ Bacon.summary_on_exit
5
+
6
+ module Kernel
7
+ private
8
+ def specification(name, &block) Bacon::Context.new(name, &block) end
9
+ end
10
+
11
+ Bacon::Context.instance_eval do
12
+ alias_method :specify, :it
13
+ end
14
+
15
+ require '../lib/autocode'
metadata CHANGED
@@ -1,85 +1,65 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.0
3
- specification_version: 1
4
2
  name: autocode
5
3
  version: !ruby/object:Gem::Version
6
- version: 0.9.3
7
- date: 2008-01-26 00:00:00 -08:00
8
- summary: Utility for auto-including, reloading, and generating classes and modules.
9
- require_paths:
10
- - lib
11
- email:
12
- homepage: http://dev.zeraweb.com/
13
- rubyforge_project:
14
- description:
4
+ version: 0.9.9
5
+ platform: ruby
6
+ authors:
7
+ - Dan Yoder
15
8
  autorequire:
16
- default_executable:
17
9
  bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-05-18 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: metaid
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ description:
25
+ email: dan@zeraweb.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - lib/autocode.rb
34
+ - test/auto_create.rb
35
+ - test/auto_eval.rb
36
+ - test/auto_load.rb
37
+ - test/helpers.rb
18
38
  has_rdoc: true
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
39
+ homepage: http://dev.zeraweb.com/
40
+ post_install_message:
41
+ rdoc_options: []
42
+
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
20
46
  requirements:
21
47
  - - ">="
22
48
  - !ruby/object:Gem::Version
23
49
  version: 1.8.6
24
50
  version:
25
- platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
- authors: []
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ requirements: []
30
58
 
31
- files:
32
- - doc/rdoc
33
- - doc/rdoc/classes
34
- - doc/rdoc/classes/Autocreate.html
35
- - doc/rdoc/classes/Autocreate.src
36
- - doc/rdoc/classes/Autocreate.src/M000004.html
37
- - doc/rdoc/classes/Autoload.html
38
- - doc/rdoc/classes/Autoload.src
39
- - doc/rdoc/classes/Autoload.src/M000001.html
40
- - doc/rdoc/classes/Autoload.src/M000002.html
41
- - doc/rdoc/classes/Autoload.src/M000003.html
42
- - doc/rdoc/classes/Reloadable.html
43
- - doc/rdoc/classes/Reloadable.src
44
- - doc/rdoc/classes/Reloadable.src/M000005.html
45
- - doc/rdoc/classes/Reloadable.src/M000006.html
46
- - doc/rdoc/created.rid
47
- - doc/rdoc/files
48
- - doc/rdoc/files/HISTORY.html
49
- - doc/rdoc/files/lib
50
- - doc/rdoc/files/lib/autocode_rb.html
51
- - doc/rdoc/files/lib/autocreate_rb.html
52
- - doc/rdoc/files/lib/autoload_rb.html
53
- - doc/rdoc/files/lib/reloadable_rb.html
54
- - doc/rdoc/files/README.html
55
- - doc/rdoc/fr_class_index.html
56
- - doc/rdoc/fr_file_index.html
57
- - doc/rdoc/fr_method_index.html
58
- - doc/rdoc/index.html
59
- - doc/rdoc/rdoc-style.css
60
- - lib/autocode.rb
61
- - lib/autocreate.rb
62
- - lib/autoload.rb
63
- - lib/reloadable.rb
59
+ rubyforge_project: autocode
60
+ rubygems_version: 1.0.1
61
+ signing_key:
62
+ specification_version: 2
63
+ summary: Utility for auto-including, reloading, and generating classes and modules.
64
64
  test_files: []
65
65
 
66
- rdoc_options: []
67
-
68
- extra_rdoc_files: []
69
-
70
- executables: []
71
-
72
- extensions: []
73
-
74
- requirements: []
75
-
76
- dependencies:
77
- - !ruby/object:Gem::Dependency
78
- name: metaid
79
- version_requirement:
80
- version_requirements: !ruby/object:Gem::Version::Requirement
81
- requirements:
82
- - - ">"
83
- - !ruby/object:Gem::Version
84
- version: 0.0.0
85
- version:
@@ -1,158 +0,0 @@
1
- <?xml version="1.0" encoding="iso-8859-1"?>
2
- <!DOCTYPE html
3
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
-
6
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
- <head>
8
- <title>Module: Autocreate</title>
9
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
- <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
- <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
- <script type="text/javascript">
13
- // <![CDATA[
14
-
15
- function popupCode( url ) {
16
- window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
- }
18
-
19
- function toggleCode( id ) {
20
- if ( document.getElementById )
21
- elem = document.getElementById( id );
22
- else if ( document.all )
23
- elem = eval( "document.all." + id );
24
- else
25
- return false;
26
-
27
- elemStyle = elem.style;
28
-
29
- if ( elemStyle.display != "block" ) {
30
- elemStyle.display = "block"
31
- } else {
32
- elemStyle.display = "none"
33
- }
34
-
35
- return true;
36
- }
37
-
38
- // Make codeblocks hidden by default
39
- document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
-
41
- // ]]>
42
- </script>
43
-
44
- </head>
45
- <body>
46
-
47
-
48
-
49
- <div id="classHeader">
50
- <table class="header-table">
51
- <tr class="top-aligned-row">
52
- <td><strong>Module</strong></td>
53
- <td class="class-name-in-header">Autocreate</td>
54
- </tr>
55
- <tr class="top-aligned-row">
56
- <td><strong>In:</strong></td>
57
- <td>
58
- <a href="../files/lib/autocreate_rb.html">
59
- lib/autocreate.rb
60
- </a>
61
- <br />
62
- </td>
63
- </tr>
64
-
65
- </table>
66
- </div>
67
- <!-- banner header -->
68
-
69
- <div id="bodyContent">
70
-
71
-
72
-
73
- <div id="contextContent">
74
-
75
- <div id="description">
76
- <p>
77
- Extending a module with <a href="Autocreate.html">Autocreate</a> allows you
78
- to specify <a href="Autocreate.html#M000004">autocreate</a> rules for that
79
- module.
80
- </p>
81
- <p>
82
- <a href="Autocreate.html">Autocreate</a> allows you to automatically
83
- created classes or modules based on a given exemplar at the time they are
84
- referenced.
85
- </p>
86
- <p>
87
- To use <a href="Autocreate.html">Autocreate</a>, mix it via <tt>extend</tt>
88
- into the class or module within which you want to <a
89
- href="Autocreate.html#M000004">autocreate</a> referenced constants.
90
- </p>
91
- <p>
92
- See the README for an example of how to use <a
93
- href="Autocreate.html">Autocreate</a>.
94
- </p>
95
-
96
- </div>
97
-
98
-
99
- </div>
100
-
101
- <div id="method-list">
102
- <h3 class="section-bar">Methods</h3>
103
-
104
- <div class="name-list">
105
- <a href="#M000004">autocreate</a>&nbsp;&nbsp;
106
- </div>
107
- </div>
108
-
109
- </div>
110
-
111
-
112
- <!-- if includes -->
113
-
114
- <div id="section">
115
-
116
-
117
-
118
-
119
-
120
-
121
-
122
-
123
- <!-- if method_list -->
124
- <div id="methods">
125
- <h3 class="section-bar">Public Instance methods</h3>
126
-
127
- <div id="method-M000004" class="method-detail">
128
- <a name="M000004"></a>
129
-
130
- <div class="method-heading">
131
- <a href="Autocreate.src/M000004.html" target="Code" class="method-signature"
132
- onclick="popupCode('Autocreate.src/M000004.html');return false;">
133
- <span class="method-name">autocreate</span><span class="method-args">( key, exemplar, &amp;block )</span>
134
- </a>
135
- </div>
136
-
137
- <div class="method-description">
138
- <p>
139
- Specifies that the constant specified by key should be autocreated using
140
- the exemplar. If a block is given, the block is further used to initialize
141
- the block once it has been cloned.
142
- </p>
143
- </div>
144
- </div>
145
-
146
-
147
- </div>
148
-
149
-
150
- </div>
151
-
152
-
153
- <div id="validator-badges">
154
- <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
155
- </div>
156
-
157
- </body>
158
- </html>