mixin 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +1 -1
- data/Rakefile +13 -0
- data/lib/metable.rb +58 -0
- data/lib/metable/class_methods.rb +20 -0
- data/lib/mixin.rb +5 -4
- data/test/mixin_case.rb +10 -0
- data/test/test_subjects/clevers.rb +24 -0
- metadata +4 -2
data/README
CHANGED
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
|
4
|
+
desc 'Default: Generate documentation.'
|
5
|
+
task :default => :rdoc
|
6
|
+
|
7
|
+
desc 'Generate documentation for Mixin.'
|
8
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
9
|
+
rdoc.rdoc_dir = 'rdoc'
|
10
|
+
rdoc.title = 'Mixin'
|
11
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
12
|
+
rdoc.rdoc_files.include('README', 'LICENSE', 'lib/**/*.rb')
|
13
|
+
end
|
data/lib/metable.rb
CHANGED
@@ -1,6 +1,64 @@
|
|
1
1
|
require 'mixin'
|
2
2
|
|
3
3
|
|
4
|
+
# == Metable - The Bonus Mixin
|
5
|
+
#
|
6
|
+
# Metable is a mixin that provides a bundle of handy methods for the aspiring
|
7
|
+
# ruby metaprogrammer.
|
8
|
+
#
|
9
|
+
# Have you ever wanted an easy way to alias a class method? Check out
|
10
|
+
# +alias_class_method+. Have you ever desired a clean way to dynamically define
|
11
|
+
# a class method in the same manner you would an instance method using
|
12
|
+
# +define_method+ ? Well feast your eyes on +define_class_method+. In fact, you can
|
13
|
+
# dynamically define a singleton method on any object the same way with
|
14
|
+
# +define_singleton_method+.
|
15
|
+
#
|
16
|
+
# Metable provides those and many more (see the full list bellow).
|
17
|
+
#
|
18
|
+
# === Public Instance Methods
|
19
|
+
# * eigen_eval
|
20
|
+
# * eigenclass
|
21
|
+
# * metaclass
|
22
|
+
# * private_singleton_method
|
23
|
+
# * protected_singleton_method
|
24
|
+
# * public_singleton_method
|
25
|
+
#
|
26
|
+
# === Private Instance Methods
|
27
|
+
# * alias_singleton_method
|
28
|
+
# * define_singleton_method
|
29
|
+
# * define_private_singleton_method
|
30
|
+
# * define_protected_singleton_method
|
31
|
+
# * define_public_singleton_method
|
32
|
+
#
|
33
|
+
# === Public Module Mixin & Class Mixin Methods
|
34
|
+
# * class_method_defined?
|
35
|
+
# * eigen_eval
|
36
|
+
# * eigenclass
|
37
|
+
# * metaclass
|
38
|
+
# * private_class_method_defined?
|
39
|
+
# * private_singleton_method
|
40
|
+
# * protected_class_method
|
41
|
+
# * protected_class_method_defined?
|
42
|
+
# * protected_singleton_method
|
43
|
+
# * public_class_method_defined?
|
44
|
+
# * public_singleton_method
|
45
|
+
#
|
46
|
+
# === Private Module Mixin & Class Mixin Methods
|
47
|
+
# * alias_class_method
|
48
|
+
# * alias_singleton_method
|
49
|
+
# * define_class_method
|
50
|
+
# * define_singleton_method
|
51
|
+
# * define_private_class_method
|
52
|
+
# * define_private_singleton_method
|
53
|
+
# * define_protected_class_method
|
54
|
+
# * define_protected_singleton_method
|
55
|
+
# * define_public_class_method
|
56
|
+
# * define_public_singleton_method
|
57
|
+
# * enclosed_attr
|
58
|
+
# * private_enclosure
|
59
|
+
# * protected_enclosure
|
60
|
+
# * public_enclosure
|
61
|
+
#
|
4
62
|
module Metable
|
5
63
|
include Metable::InstanceMethods
|
6
64
|
extend_class_mixin Metable::ClassMethods
|
@@ -51,6 +51,20 @@ module Metable
|
|
51
51
|
# invoked on that instance. The _access_ argument can be a symbol or string
|
52
52
|
# representing the access level for the enclosure method (public, private,
|
53
53
|
# or protected). The default access level is +private+.
|
54
|
+
#
|
55
|
+
# class Foo
|
56
|
+
# include Metable
|
57
|
+
# enclosed_attr(:time_of_enclosure, :public) { Time.now }
|
58
|
+
# end
|
59
|
+
#
|
60
|
+
# foo = Foo.new
|
61
|
+
# sleep 7
|
62
|
+
# Time.now -> Fri Sep 05 16:20:00 -0700 2008
|
63
|
+
# foo.time_of_enclosure -> Fri Sep 05 16:20:00 -0700 2008
|
64
|
+
# sleep 86407
|
65
|
+
# foo.time_of_enclosure -> Fri Sep 05 16:20:00 -0700 2008
|
66
|
+
# foo.instance_variables -> []
|
67
|
+
#
|
54
68
|
def enclosed_attr(name, access = :private, &block) # :doc:
|
55
69
|
define_method name do
|
56
70
|
ea = instance_eval &block
|
@@ -61,14 +75,20 @@ module Metable
|
|
61
75
|
end
|
62
76
|
|
63
77
|
|
78
|
+
# Equivalent to calling "<tt>enclosed_attr _name_, :public, <em>&block</em></tt>"
|
79
|
+
# on each _name_ in turn.
|
64
80
|
def public_enclosure(*names, &block) # :doc:
|
65
81
|
names.each { |name| enclosed_attr name, :public, &block }
|
66
82
|
end
|
67
83
|
|
84
|
+
# Equivalent to calling "<tt>enclosed_attr _name_, :private, <em>&block</em></tt>"
|
85
|
+
# on each _name_ in turn.
|
68
86
|
def private_enclosure(*names, &block) # :doc:
|
69
87
|
names.each { |name| enclosed_attr name, :private, &block }
|
70
88
|
end
|
71
89
|
|
90
|
+
# Equivalent to calling "<tt>enclosed_attr _name_, :protected, <em>&block</em></tt>"
|
91
|
+
# on each _name_ in turn.
|
72
92
|
def protected_enclosure(*names, &block) # :doc:
|
73
93
|
names.each { |name| enclosed_attr name, :protected, &block }
|
74
94
|
end
|
data/lib/mixin.rb
CHANGED
@@ -8,7 +8,8 @@ module Mixin
|
|
8
8
|
include Metable::InstanceMethods
|
9
9
|
extend Metable::ClassMethods
|
10
10
|
|
11
|
-
|
11
|
+
|
12
|
+
class ModuleMixin < SingletonMixin = Class.new(Module) # :nodoc:
|
12
13
|
include Metable::InstanceMethods
|
13
14
|
|
14
15
|
def initialize(mixin)
|
@@ -25,7 +26,7 @@ module Mixin
|
|
25
26
|
end
|
26
27
|
|
27
28
|
|
28
|
-
enclosed_attr(:__class_mixin__) {
|
29
|
+
enclosed_attr(:__class_mixin__) { SingletonMixin.new }
|
29
30
|
enclosed_attr(:__module_mixin__) { ModuleMixin.new(self) }
|
30
31
|
|
31
32
|
|
@@ -94,7 +95,7 @@ module Mixin
|
|
94
95
|
|
95
96
|
|
96
97
|
# Works the same as +class_mixin+ except that the invoking module's
|
97
|
-
# +module_mixin+ is instead extended to the invoking module
|
98
|
+
# +module_mixin+ is instead extended to the invoking module itself rather
|
98
99
|
# than its including classes.
|
99
100
|
#
|
100
101
|
# module Active
|
@@ -128,7 +129,7 @@ module Mixin
|
|
128
129
|
|
129
130
|
|
130
131
|
def included(submodule)
|
131
|
-
if submodule.kind_of?
|
132
|
+
if submodule.kind_of?(Class) || submodule.kind_of?(SingletonMixin)
|
132
133
|
submodule.extend __class_mixin__
|
133
134
|
else
|
134
135
|
submodule.extend_module_mixin __module_mixin__
|
data/test/mixin_case.rb
CHANGED
@@ -217,4 +217,14 @@ class MixinTest < Test::Unit::TestCase
|
|
217
217
|
assert Meeper.rico? && Meeper.suave?
|
218
218
|
end
|
219
219
|
|
220
|
+
|
221
|
+
def test_tips_and_tricks
|
222
|
+
load 'clevers.rb'
|
223
|
+
|
224
|
+
assert Clever.trick?
|
225
|
+
assert Adroit.trick?
|
226
|
+
assert Deft.technique?
|
227
|
+
assert Adroit.technique?
|
228
|
+
end
|
229
|
+
|
220
230
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Clever
|
2
|
+
extend_module_mixin class_mixin
|
3
|
+
|
4
|
+
class_mixin do
|
5
|
+
def trick?
|
6
|
+
true
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
module Deft
|
13
|
+
extend_module_mixin self
|
14
|
+
extend_class_mixin self
|
15
|
+
|
16
|
+
def technique?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
class Adroit
|
23
|
+
include Clever, Deft
|
24
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mixin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hersch Stevenson (xian)
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-09-
|
12
|
+
date: 2008-09-08 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -35,9 +35,11 @@ files:
|
|
35
35
|
- test/test_subjects/nudgers.rb
|
36
36
|
- test/test_subjects/includers.rb
|
37
37
|
- test/test_subjects/soopers.rb
|
38
|
+
- test/test_subjects/clevers.rb
|
38
39
|
- test/mixin_case.rb
|
39
40
|
- README
|
40
41
|
- LICENSE
|
42
|
+
- Rakefile
|
41
43
|
has_rdoc: true
|
42
44
|
homepage: http://www.persapient.com/mixin
|
43
45
|
post_install_message:
|