module_creation_helper 0.0.2 → 0.0.3
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/CHANGELOG +13 -0
- data/MIT-LICENSE +1 -1
- data/README +31 -21
- data/Rakefile +4 -4
- data/lib/module_creation_helper.rb +64 -64
- data/test/test_helper.rb +5 -5
- metadata +4 -3
data/CHANGELOG
ADDED
data/MIT-LICENSE
CHANGED
data/README
CHANGED
@@ -1,17 +1,21 @@
|
|
1
1
|
= module_creation_helper
|
2
2
|
|
3
|
-
module_creation_helper adds a helper method for creating new modules and classes
|
3
|
+
+module_creation_helper+ adds a helper method for creating new modules and classes
|
4
4
|
at runtime.
|
5
5
|
|
6
6
|
== Resources
|
7
7
|
|
8
|
+
API
|
9
|
+
|
10
|
+
* http://api.pluginaweek.org/module_creation_helper
|
11
|
+
|
8
12
|
Wiki
|
9
13
|
|
10
14
|
* http://wiki.pluginaweek.org/Module_creation_helper
|
11
15
|
|
12
16
|
Announcement
|
13
17
|
|
14
|
-
* http://www.pluginaweek.org/2007/01/04/10-from-anonymous-to-named-and-back-again-a-tale-of-modules-and-classes
|
18
|
+
* http://www.pluginaweek.org/2007/01/04/10-from-anonymous-to-named-and-back-again-a-tale-of-modules-and-classes
|
15
19
|
|
16
20
|
Source
|
17
21
|
|
@@ -24,11 +28,10 @@ Development
|
|
24
28
|
== Description
|
25
29
|
|
26
30
|
Creating modules and classes at runtime isn't the easiest and most intuitive
|
27
|
-
process
|
28
|
-
|
29
|
-
with an actual name.
|
31
|
+
process. Although often used for anonymous classes, there are many times where
|
32
|
+
you will want to associate a runtime class with an actual name.
|
30
33
|
|
31
|
-
|
34
|
+
Traditionally, you would create new classes like so:
|
32
35
|
|
33
36
|
>> c = Class.new
|
34
37
|
=> #<Class:0x480e388>
|
@@ -36,10 +39,9 @@ Normally, you would create new classes and associate them with a name like so:
|
|
36
39
|
=> Foo
|
37
40
|
|
38
41
|
Although this isn't very hard, there are two problems:
|
39
|
-
(1) It's a repetitive process that should be DRYed
|
40
|
-
|
41
|
-
|
42
|
-
access to the name of the class.
|
42
|
+
(1) It's a repetitive process that should be DRYed.
|
43
|
+
(2) Callbacks that are invoked while the class is being created do not know the
|
44
|
+
name of the class.
|
43
45
|
|
44
46
|
To understand the second problem, consider the following:
|
45
47
|
|
@@ -59,14 +61,13 @@ example,
|
|
59
61
|
As you can see from output in this example, since the class has not yet been
|
60
62
|
assigned to a constant, it is anonymous and does not yet have a name.
|
61
63
|
|
62
|
-
To address these
|
63
|
-
Module#create
|
64
|
+
To address these issues, the functionality is encapsulated into a new method,
|
65
|
+
<tt>Module#create</tt>. Since the method is defined in Module, it is also available to
|
64
66
|
Class since Class inherits from Module.
|
65
67
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
evaluated or has already been evaluated.
|
68
|
+
== Usage
|
69
|
+
|
70
|
+
=== Creating new classes/modules
|
70
71
|
|
71
72
|
Using the same example as before,
|
72
73
|
|
@@ -75,16 +76,21 @@ Using the same example as before,
|
|
75
76
|
=> Bar
|
76
77
|
|
77
78
|
As you can see, the name of the class is now available during the +inherited+
|
78
|
-
callback and is automatically assigned to the 'Bar' constant in Object.
|
79
|
-
|
79
|
+
callback and is automatically assigned to the 'Bar' constant in Object.
|
80
|
+
|
81
|
+
=== Specifying the parent class/module
|
82
|
+
|
83
|
+
In addition to specifying the superclass, you can also specify the parent
|
80
84
|
module/class like so:
|
81
85
|
|
82
86
|
>> c = Class.create('Bar', :superclass => Foo, :parent => MyModule)
|
83
87
|
inherited class: MyModule::Bar, name: MyModule::Bar
|
84
88
|
=> MyModule::Bar
|
85
89
|
|
86
|
-
|
87
|
-
|
90
|
+
=== Defining class/module methods
|
91
|
+
|
92
|
+
As you normally could when creating a new class, you can provide an additional
|
93
|
+
block that defines the body of the class. For example,
|
88
94
|
|
89
95
|
>> c = Class.create('Bar', :superclass => Foo, :parent => MyModule) do
|
90
96
|
?> def say_hello
|
@@ -94,4 +100,8 @@ additional block that defines the body of the class. For example,
|
|
94
100
|
inherited class: MyModule::Bar, name: MyModule::Bar
|
95
101
|
=> Bar
|
96
102
|
>> Bar.new.say_hello
|
97
|
-
=> "hello"
|
103
|
+
=> "hello"
|
104
|
+
|
105
|
+
== Dependencies
|
106
|
+
|
107
|
+
This plugin does not depend on the presence of any other plugins.
|
data/Rakefile
CHANGED
@@ -4,7 +4,7 @@ require 'rake/gempackagetask'
|
|
4
4
|
require 'rake/contrib/sshpublisher'
|
5
5
|
|
6
6
|
PKG_NAME = 'module_creation_helper'
|
7
|
-
PKG_VERSION = '0.0.
|
7
|
+
PKG_VERSION = '0.0.3'
|
8
8
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
9
9
|
RUBY_FORGE_PROJECT = 'pluginaweek'
|
10
10
|
|
@@ -33,13 +33,13 @@ spec = Gem::Specification.new do |s|
|
|
33
33
|
s.platform = Gem::Platform::RUBY
|
34
34
|
s.summary = 'Adds a helper method for creating new modules and classes at runtime.'
|
35
35
|
|
36
|
-
s.files = FileList['{lib,
|
36
|
+
s.files = FileList['{lib,test}/**/*'].to_a + %w(CHANGELOG init.rb MIT-LICENSE Rakefile README)
|
37
37
|
s.require_path = 'lib'
|
38
38
|
s.autorequire = 'module_creation_helper'
|
39
39
|
s.has_rdoc = true
|
40
40
|
s.test_files = Dir['test/**/*_test.rb']
|
41
41
|
|
42
|
-
s.author = 'Aaron Pfeifer
|
42
|
+
s.author = 'Aaron Pfeifer, Neil Abraham'
|
43
43
|
s.email = 'info@pluginaweek.org'
|
44
44
|
s.homepage = 'http://www.pluginaweek.org'
|
45
45
|
end
|
@@ -76,4 +76,4 @@ task :release => [:gem, :package] do
|
|
76
76
|
|
77
77
|
ruby_forge.add_release(RUBY_FORGE_PROJECT, PKG_NAME, PKG_VERSION, file)
|
78
78
|
end
|
79
|
-
end
|
79
|
+
end
|
@@ -1,64 +1,64 @@
|
|
1
|
-
module PluginAWeek #:nodoc:
|
2
|
-
module CoreExtensions #:nodoc:
|
3
|
-
module Module #:nodoc:
|
4
|
-
module ModuleCreationHelper
|
5
|
-
# Creates a new module with the specified name. This is essentially the
|
6
|
-
# same as actually defining the module like so:
|
7
|
-
#
|
8
|
-
# module NewModule
|
9
|
-
# end
|
10
|
-
#
|
11
|
-
# or as a class:
|
12
|
-
#
|
13
|
-
# class NewClass < SuperKlass
|
14
|
-
# end
|
15
|
-
#
|
16
|
-
# Configuration options:
|
17
|
-
# <tt>superclass</tt> - The class to inherit from. This only applies when using Class#create. Default is Object.
|
18
|
-
# <tt>parent</tt> - The class/module that contains this module. Default is Object.
|
19
|
-
#
|
20
|
-
# Examples:
|
21
|
-
#
|
22
|
-
# Module.create('Foo') # => Foo
|
23
|
-
# Module.create('Bar', :parent => Foo) # => Foo::Bar
|
24
|
-
# Class.create('Waddle') # => Waddle
|
25
|
-
# Class.create('Widdle', :parent => Waddle) # => Waddle::Widdle
|
26
|
-
# Class.create('Woddle', :superclass => Waddle::Widdle, :parent => Waddle) # => Waddle::Woddle
|
27
|
-
# Waddle::Woddle.superclass # => Waddle::Widdle
|
28
|
-
def create(name, options = {}, &block)
|
29
|
-
options.assert_valid_keys(
|
30
|
-
:superclass,
|
31
|
-
:parent
|
32
|
-
)
|
33
|
-
raise ArgumentError, 'Modules cannot have superclasses' if options[:superclass] && self.to_s == 'Module'
|
34
|
-
|
35
|
-
options.reverse_merge!(
|
36
|
-
:superclass => ::Object,
|
37
|
-
:parent => ::Object
|
38
|
-
)
|
39
|
-
parent = options[:parent]
|
40
|
-
superclass = options[:superclass]
|
41
|
-
|
42
|
-
if superclass != ::Object
|
43
|
-
superclass = " < ::#{superclass}"
|
44
|
-
else
|
45
|
-
superclass = ''
|
46
|
-
end
|
47
|
-
|
48
|
-
parent.class_eval <<-end_eval
|
49
|
-
#{self.to_s.downcase} #{name}#{superclass}
|
50
|
-
end
|
51
|
-
end_eval
|
52
|
-
|
53
|
-
mod = parent.const_get(name)
|
54
|
-
mod.class_eval(&block) if block_given?
|
55
|
-
mod
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
|
63
|
-
extend PluginAWeek::CoreExtensions::Module::ModuleCreationHelper
|
64
|
-
end
|
1
|
+
module PluginAWeek #:nodoc:
|
2
|
+
module CoreExtensions #:nodoc:
|
3
|
+
module Module #:nodoc:
|
4
|
+
module ModuleCreationHelper
|
5
|
+
# Creates a new module with the specified name. This is essentially the
|
6
|
+
# same as actually defining the module like so:
|
7
|
+
#
|
8
|
+
# module NewModule
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
# or as a class:
|
12
|
+
#
|
13
|
+
# class NewClass < SuperKlass
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# Configuration options:
|
17
|
+
# <tt>superclass</tt> - The class to inherit from. This only applies when using Class#create. Default is Object.
|
18
|
+
# <tt>parent</tt> - The class/module that contains this module. Default is Object.
|
19
|
+
#
|
20
|
+
# Examples:
|
21
|
+
#
|
22
|
+
# Module.create('Foo') # => Foo
|
23
|
+
# Module.create('Bar', :parent => Foo) # => Foo::Bar
|
24
|
+
# Class.create('Waddle') # => Waddle
|
25
|
+
# Class.create('Widdle', :parent => Waddle) # => Waddle::Widdle
|
26
|
+
# Class.create('Woddle', :superclass => Waddle::Widdle, :parent => Waddle) # => Waddle::Woddle
|
27
|
+
# Waddle::Woddle.superclass # => Waddle::Widdle
|
28
|
+
def create(name, options = {}, &block)
|
29
|
+
options.assert_valid_keys(
|
30
|
+
:superclass,
|
31
|
+
:parent
|
32
|
+
)
|
33
|
+
raise ArgumentError, 'Modules cannot have superclasses' if options[:superclass] && self.to_s == 'Module'
|
34
|
+
|
35
|
+
options.reverse_merge!(
|
36
|
+
:superclass => ::Object,
|
37
|
+
:parent => ::Object
|
38
|
+
)
|
39
|
+
parent = options[:parent]
|
40
|
+
superclass = options[:superclass]
|
41
|
+
|
42
|
+
if superclass != ::Object
|
43
|
+
superclass = " < ::#{superclass}"
|
44
|
+
else
|
45
|
+
superclass = ''
|
46
|
+
end
|
47
|
+
|
48
|
+
parent.class_eval <<-end_eval
|
49
|
+
#{self.to_s.downcase} #{name}#{superclass}
|
50
|
+
end
|
51
|
+
end_eval
|
52
|
+
|
53
|
+
mod = parent.const_get(name)
|
54
|
+
mod.class_eval(&block) if block_given?
|
55
|
+
mod
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
::Module.class_eval do
|
63
|
+
extend PluginAWeek::CoreExtensions::Module::ModuleCreationHelper
|
64
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require 'rubygems'
|
3
|
-
require 'active_support'
|
4
|
-
|
5
|
-
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'active_support'
|
4
|
+
|
5
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
6
6
|
require File.dirname(__FILE__) + '/../init'
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: module_creation_helper
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.0.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.0.3
|
7
|
+
date: 2007-09-18 00:00:00 -04:00
|
8
8
|
summary: Adds a helper method for creating new modules and classes at runtime.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -27,11 +27,12 @@ signing_key:
|
|
27
27
|
cert_chain:
|
28
28
|
post_install_message:
|
29
29
|
authors:
|
30
|
-
- Aaron Pfeifer
|
30
|
+
- Aaron Pfeifer, Neil Abraham
|
31
31
|
files:
|
32
32
|
- lib/module_creation_helper.rb
|
33
33
|
- test/test_helper.rb
|
34
34
|
- test/module_creation_helper_test.rb
|
35
|
+
- CHANGELOG
|
35
36
|
- init.rb
|
36
37
|
- MIT-LICENSE
|
37
38
|
- Rakefile
|