cuts 0.0.1 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +1 -0
- data/HISTORY +18 -0
- data/MANIFEST +22 -0
- data/NOTES +1 -6
- data/Rakefile +9 -1
- data/VERSION +1 -0
- data/lib/cuts.rb +0 -1
- data/lib/cuts/aop.rb +5 -4
- data/lib/cuts/cut.rb +56 -34
- data/meta/abstract +3 -0
- data/meta/contact +1 -0
- data/meta/created +1 -0
- data/meta/homepage +1 -0
- data/meta/license +1 -0
- data/meta/requires +1 -0
- data/meta/summary +1 -0
- data/test/test_aop.rb +49 -0
- data/test/test_cut.rb +207 -0
- metadata +52 -23
- data/CHANGES +0 -16
- data/meta/project.yaml +0 -23
- data/meta/unixname +0 -1
- data/meta/version +0 -1
- data/setup.rb +0 -1467
- data/test/template.rb +0 -16
data/COPYING
CHANGED
data/HISTORY
ADDED
data/MANIFEST
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Rakefile
|
2
|
+
test
|
3
|
+
test/test_cut.rb
|
4
|
+
test/test_aop.rb
|
5
|
+
NOTES
|
6
|
+
README
|
7
|
+
HISTORY
|
8
|
+
meta
|
9
|
+
meta/created
|
10
|
+
meta/homepage
|
11
|
+
meta/summary
|
12
|
+
meta/abstract
|
13
|
+
meta/license
|
14
|
+
meta/requires
|
15
|
+
meta/contact
|
16
|
+
lib
|
17
|
+
lib/cuts.rb
|
18
|
+
lib/cuts
|
19
|
+
lib/cuts/aop.rb
|
20
|
+
lib/cuts/cut.rb
|
21
|
+
VERSION
|
22
|
+
COPYING
|
data/NOTES
CHANGED
@@ -1,6 +1 @@
|
|
1
|
-
|
2
|
-
# This is a place to put release notes.
|
3
|
-
# Like CHANGES this is also uploaded in the release process.
|
4
|
-
# This is good place to mention major changes and things
|
5
|
-
# users might need to do to take them into account.
|
6
|
-
|
1
|
+
This release removes all dependencies on Facets.
|
data/Rakefile
CHANGED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
cuts 0.0.4 alpha (2008-09-18)
|
data/lib/cuts.rb
CHANGED
data/lib/cuts/aop.rb
CHANGED
@@ -13,9 +13,9 @@
|
|
13
13
|
#
|
14
14
|
# - Can JointPoint and Target be the same class?
|
15
15
|
|
16
|
-
require 'facets/kernel/object'
|
17
|
-
require 'facets/module/methods'
|
18
|
-
require '
|
16
|
+
#require 'facets/kernel/object'
|
17
|
+
#require 'facets/module/methods'
|
18
|
+
require 'cuts/cut'
|
19
19
|
|
20
20
|
#
|
21
21
|
|
@@ -109,7 +109,8 @@ def cross_cut(klass)
|
|
109
109
|
Cut.new(klass) do
|
110
110
|
define_method :__base__ do klass end
|
111
111
|
|
112
|
-
|
112
|
+
methods = public_instance_methods + private_instance_methods + protected_instance_methods
|
113
|
+
methods.each do |meth|
|
113
114
|
undef_method(meth) unless meth.to_s =~ /(^__|initialize$|p$|class$|inspect$)/
|
114
115
|
end
|
115
116
|
|
data/lib/cuts/cut.rb
CHANGED
@@ -1,34 +1,14 @@
|
|
1
|
-
#
|
1
|
+
# cut.rb
|
2
|
+
# Copyright (c) 2005,2008 Thomas Sawyer
|
2
3
|
#
|
3
|
-
#
|
4
|
+
# Ruby License
|
4
5
|
#
|
5
|
-
#
|
6
|
+
# This module is free software. You may use, modify, and/or redistribute this
|
7
|
+
# software under the same terms as Ruby.
|
6
8
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
# COPYRIGHT:
|
12
|
-
#
|
13
|
-
# Copyright (c) 2005 Thomas Sawyer
|
14
|
-
#
|
15
|
-
# LICENSE:
|
16
|
-
#
|
17
|
-
# Ruby License
|
18
|
-
#
|
19
|
-
# This module is free software. You may use, modify, and/or redistribute this
|
20
|
-
# software under the same terms as Ruby.
|
21
|
-
#
|
22
|
-
# This program is distributed in the hope that it will be useful, but WITHOUT
|
23
|
-
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
24
|
-
# FOR A PARTICULAR PURPOSE.
|
25
|
-
#
|
26
|
-
# AUTHORS:
|
27
|
-
#
|
28
|
-
# - Thomas Sawyer
|
29
|
-
|
30
|
-
require 'facets/module/name'
|
31
|
-
require 'facets/kernel/silence'
|
9
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
10
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
11
|
+
# FOR A PARTICULAR PURPOSE.
|
32
12
|
|
33
13
|
# = Cut
|
34
14
|
#
|
@@ -98,8 +78,7 @@ require 'facets/kernel/silence'
|
|
98
78
|
# transparency.
|
99
79
|
#
|
100
80
|
# Due to limitation in meta-programming Ruby as this level, the
|
101
|
-
# transparency isn't perfect, but it's fairly close
|
102
|
-
# to improve it.
|
81
|
+
# transparency isn't perfect, but it's fairly close.
|
103
82
|
|
104
83
|
class Cut
|
105
84
|
|
@@ -111,10 +90,10 @@ class Cut
|
|
111
90
|
cut.send(:include, Transparency)
|
112
91
|
cut.extend MetaTransparency
|
113
92
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
93
|
+
v = $VERBOSE
|
94
|
+
$VERBOSE = false
|
95
|
+
klass.modspace::const_set(klass.basename, cut)
|
96
|
+
$VERBOSE = v
|
118
97
|
|
119
98
|
return cut
|
120
99
|
end
|
@@ -188,3 +167,46 @@ module Kernel
|
|
188
167
|
end
|
189
168
|
end
|
190
169
|
|
170
|
+
class Module
|
171
|
+
# Returns the root name of the module/class.
|
172
|
+
#
|
173
|
+
# module Example
|
174
|
+
# class Demo
|
175
|
+
# end
|
176
|
+
# end
|
177
|
+
#
|
178
|
+
# Demo.name #=> "Example::Demo"
|
179
|
+
# Demo.basename #=> "Demo"
|
180
|
+
#
|
181
|
+
# For anonymous modules this will provide a basename
|
182
|
+
# based on Module#inspect.
|
183
|
+
#
|
184
|
+
# m = Module.new
|
185
|
+
# m.inspect #=> "#<Module:0xb7bb0434>"
|
186
|
+
# m.basename #=> "Module_0xb7bb0434"
|
187
|
+
#
|
188
|
+
def basename
|
189
|
+
if name and not name.empty?
|
190
|
+
name.gsub(/^.*::/, '')
|
191
|
+
else
|
192
|
+
nil #inspect.gsub('#<','').gsub('>','').sub(':', '_')
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# Returns the module's container module.
|
197
|
+
#
|
198
|
+
# module Example
|
199
|
+
# class Demo
|
200
|
+
# end
|
201
|
+
# end
|
202
|
+
#
|
203
|
+
# Example::Demo.modspace #=> Example
|
204
|
+
#
|
205
|
+
# See also Module#basename.
|
206
|
+
#
|
207
|
+
def modspace
|
208
|
+
space = name[ 0...(name.rindex( '::' ) || 0)]
|
209
|
+
space.empty? ? Object : eval(space)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
data/meta/abstract
ADDED
data/meta/contact
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
tigerops-community@rubyforge.org
|
data/meta/created
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2008-02-12
|
data/meta/homepage
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
http://cuts.rubyforge.org
|
data/meta/license
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
MIT
|
data/meta/requires
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
facets >=2.4.4
|
data/meta/summary
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Cut-based AOP for Ruby
|
data/test/test_aop.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'cuts'
|
3
|
+
|
4
|
+
class TestAop < Test::Unit::TestCase
|
5
|
+
|
6
|
+
class X
|
7
|
+
def x; "x"; end
|
8
|
+
def y; "y"; end
|
9
|
+
def q; "<" + x + ">"; end
|
10
|
+
end
|
11
|
+
|
12
|
+
Xa = Aspect.new do
|
13
|
+
join :x do |jp|
|
14
|
+
jp == :x
|
15
|
+
end
|
16
|
+
|
17
|
+
def x(target); '{' + target.super + '}'; end
|
18
|
+
end
|
19
|
+
|
20
|
+
X.apply(Xa)
|
21
|
+
|
22
|
+
def setup
|
23
|
+
@x1 = X.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_class
|
27
|
+
assert_equal(X, @x1.class)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_public_methods
|
31
|
+
meths = @x1.public_methods(false)
|
32
|
+
assert(meths.include?("y"))
|
33
|
+
assert(meths.include?("q"))
|
34
|
+
assert(meths.include?("x"))
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_x
|
38
|
+
assert_equal("{x}", @x1.x)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_y
|
42
|
+
assert_equal("y", @x1.y)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_q
|
46
|
+
assert_equal("<{x}>", @x1.q)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
data/test/test_cut.rb
ADDED
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'cuts'
|
3
|
+
|
4
|
+
class TestCut < Test::Unit::TestCase
|
5
|
+
|
6
|
+
class X
|
7
|
+
def x; "x"; end
|
8
|
+
end
|
9
|
+
|
10
|
+
Xc = Cut.new(X) do
|
11
|
+
def x; '{' + super + '}'; end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_method_is_wrapped_by_advice
|
15
|
+
o = X.new
|
16
|
+
assert_equal("{x}", o.x)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
=begin
|
23
|
+
require 'facets/cut.rb'
|
24
|
+
|
25
|
+
require 'test/unit'
|
26
|
+
|
27
|
+
class TestCut1 < Test::Unit::TestCase
|
28
|
+
|
29
|
+
class F
|
30
|
+
def f ; "f" ; end
|
31
|
+
end
|
32
|
+
|
33
|
+
cut :G < F do
|
34
|
+
join :f => :f
|
35
|
+
def f(target); '<'+target.super+'>' ; end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_1_01
|
39
|
+
f = F.new
|
40
|
+
assert_equal( "<f>", f.f )
|
41
|
+
assert_equal( F, f.class )
|
42
|
+
assert_equal( F, f.object_class )
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_1_02
|
46
|
+
assert( G )
|
47
|
+
assert_equal( "TestCut1::G", G.name )
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
# Test multiple cuts.
|
53
|
+
|
54
|
+
class TestCut2 < Test::Unit::TestCase
|
55
|
+
|
56
|
+
class F
|
57
|
+
def f ; "f" ; end
|
58
|
+
end
|
59
|
+
|
60
|
+
cut :G < F do
|
61
|
+
join :f => :f
|
62
|
+
def f(target); '<'+target.super+'>' ; end
|
63
|
+
end
|
64
|
+
|
65
|
+
cut :Q < F do
|
66
|
+
join :f => :f
|
67
|
+
def f(target); '['+target.super+']'; end
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_2_01
|
71
|
+
assert_equal( [Q, G], F.cuts )
|
72
|
+
assert_equal( [Q, G], F.predecessors )
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_2_02
|
76
|
+
f = F.new
|
77
|
+
assert_equal( F, f.class )
|
78
|
+
assert_equal( F, f.object_class )
|
79
|
+
assert_equal( "[<f>]", f.f )
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_2_03
|
83
|
+
assert( G )
|
84
|
+
assert_equal( "TestCut2::G", G.name )
|
85
|
+
assert( Q )
|
86
|
+
assert_equal( "TestCut2::Q", Q.name )
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
|
93
|
+
class TestCut3 < Test::Unit::TestCase
|
94
|
+
|
95
|
+
class C
|
96
|
+
def r1; "r1"; end
|
97
|
+
end
|
98
|
+
|
99
|
+
cut :A < C do
|
100
|
+
def r1
|
101
|
+
b1( target( :r1 ){ super } )
|
102
|
+
end
|
103
|
+
def b1( target )
|
104
|
+
'(' + target.super + ')'
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_3_01
|
109
|
+
c = C.new
|
110
|
+
assert_equal( '(r1)', c.r1 )
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
# Test the addition of new methods and module inclusions
|
116
|
+
# after the cut is defined with dynamic joining.
|
117
|
+
|
118
|
+
class TestCut4 < Test::Unit::TestCase
|
119
|
+
|
120
|
+
class C
|
121
|
+
def r1; "r1"; end
|
122
|
+
def r2; "r2"; end
|
123
|
+
def j1; "j1"; end
|
124
|
+
def j2; "j2"; end
|
125
|
+
end
|
126
|
+
|
127
|
+
cut :A < C do
|
128
|
+
|
129
|
+
join :wrappy => lambda { |jp| /^r/ =~ jp }
|
130
|
+
join :square => :j1, :flare => :j2
|
131
|
+
|
132
|
+
def wrappy( target )
|
133
|
+
'{'+target.super+'}'
|
134
|
+
end
|
135
|
+
|
136
|
+
def square(target) '['+target.super+']' end
|
137
|
+
def flare(target) '*'+target.super+'*' end
|
138
|
+
end
|
139
|
+
|
140
|
+
class C
|
141
|
+
def r3; "r3"; end
|
142
|
+
end
|
143
|
+
|
144
|
+
module M
|
145
|
+
def r4 ; "r4"; end
|
146
|
+
end
|
147
|
+
|
148
|
+
class C
|
149
|
+
include M
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_4_01
|
153
|
+
c = C.new
|
154
|
+
assert_equal( '{r1}', c.r1 )
|
155
|
+
assert_equal( '{r2}', c.r2 )
|
156
|
+
assert_equal( '{r3}', c.r3 )
|
157
|
+
assert_equal( '{r4}', c.r4 )
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_4_02
|
161
|
+
c = C.new
|
162
|
+
assert_equal( '[j1]', c.j1 )
|
163
|
+
assert_equal( '*j2*', c.j2 )
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
|
168
|
+
# Test subclassing.
|
169
|
+
|
170
|
+
class TestCut5 < Test::Unit::TestCase
|
171
|
+
|
172
|
+
class C
|
173
|
+
def r1; "r1"; end
|
174
|
+
def r2; "r2"; end
|
175
|
+
end
|
176
|
+
|
177
|
+
cut :C1 < C do
|
178
|
+
join :wrap1 => [:r1, :r2]
|
179
|
+
|
180
|
+
def wrap1( target )
|
181
|
+
'{' + target.super + '}'
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
cut :C2 < C do
|
186
|
+
join :wrap2 => [:r1, :r2]
|
187
|
+
|
188
|
+
def wrap2( target )
|
189
|
+
'[' + target.super + ']'
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
class D < C
|
194
|
+
def r1; '<' + super + '>'; end
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_5_01
|
198
|
+
c = C.new
|
199
|
+
assert_equal( '[{r1}]', c.r1 )
|
200
|
+
assert_equal( '[{r2}]', c.r2 )
|
201
|
+
d = D.new
|
202
|
+
assert_equal( '<[{r1}]>', d.r1 )
|
203
|
+
assert_equal( '[{r2}]', d.r2 )
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
=end
|