cuts 0.0.1 → 0.0.4

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/COPYING CHANGED
@@ -1,3 +1,4 @@
1
+ .
1
2
  GNU GENERAL PUBLIC LICENSE
2
3
  Version 3, 29 June 2007
3
4
 
data/HISTORY ADDED
@@ -0,0 +1,18 @@
1
+ = Cuts Change History
2
+
3
+ == 0.0.4 // 2008-03-05
4
+
5
+ * Added Rakefile to run tests.
6
+
7
+ == 0.0.3 // 2008-04-06
8
+
9
+ * Working release.
10
+
11
+ == 0.0.1 // 2008-03-05
12
+
13
+ * First release.
14
+
15
+ == 0.0.0 // 2008-03-04
16
+
17
+ * Started project.
18
+
@@ -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
@@ -1,2 +1,10 @@
1
- require File.join(File.dirname(__FILE__), "setup.rb")
2
1
 
2
+ desc "run tests"
3
+
4
+ task :test do
5
+ $LOAD_PATH.unshift './lib'
6
+
7
+ Dir['test/*'].each do |testfile|
8
+ load testfile
9
+ end
10
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ cuts 0.0.4 alpha (2008-09-18)
@@ -1,2 +1 @@
1
- require 'cuts/cut.rb'
2
1
  require 'cuts/aop.rb'
@@ -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 'facets/cut'
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
- all_instance_methods.each do |meth|
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
 
@@ -1,34 +1,14 @@
1
- # TITLE:
1
+ # cut.rb
2
+ # Copyright (c) 2005,2008 Thomas Sawyer
2
3
  #
3
- # Cut
4
+ # Ruby License
4
5
  #
5
- # SUMMARY:
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
- # By definition, a Cut is a *transparent* subclass.
8
- # Thay serve as the basis of Cut-based AOP, by providing
9
- # a clean wrapping mechinism.
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, and we continue
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
- # TODO Shutdown warning
115
- silence_warnings do
116
- klass.modspace::const_set(klass.basename, cut)
117
- end
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
+
@@ -0,0 +1,3 @@
1
+ Cuts is an expiremental implementation of cut-based
2
+ AOP for Ruby written in pure Ruby.
3
+
@@ -0,0 +1 @@
1
+ tigerops-community@rubyforge.org
@@ -0,0 +1 @@
1
+ 2008-02-12
@@ -0,0 +1 @@
1
+ http://cuts.rubyforge.org
@@ -0,0 +1 @@
1
+ MIT
@@ -0,0 +1 @@
1
+ facets >=2.4.4
@@ -0,0 +1 @@
1
+ Cut-based AOP for Ruby
@@ -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
@@ -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