cuts 1.0.0 → 1.1.0

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.
@@ -0,0 +1,82 @@
1
+ = Cuts - Cut-based AOP for Ruby
2
+
3
+ {Homepage}[http://rubyworks.github.com/cuts] |
4
+ {Source Code}[http://github.com/rubyworks/cuts] |
5
+ {Issue Tracker}[http://github.com/rubyworks/cuts/issues]
6
+
7
+ {<img src="http://travis-ci.org/rubyworks/cuts.png" />}[http://travis-ci.org/rubyworks/cuts]
8
+
9
+
10
+ == Description
11
+
12
+ Cuts is an expiremental pure-Ruby implimentation of cut-base AOP.
13
+ Cuts are a failry low-level system, so implementing them in pure-Ruby is no
14
+ simple accomplishment, even for a language as reflective and metaprogrammable
15
+ as Ruby.
16
+
17
+
18
+ == History
19
+
20
+ Cuts started it's life as a discussion about AOP on Ruby-talk, which led to
21
+ a in-depth discussion between Trans and Peter Vanbroekhoven. The outcome of those talks
22
+ were three projects. {Suby}[http://suby.rubyforge.org] an early expiremental
23
+ branch of Ruby; the RCRFoundry, a section of the Ruby Garden Wiki dedicated to jointly
24
+ developing RCRs; and the {Cut-based AOP RCR}[rcr.html]. The RCR of course,
25
+ ultimately led to this project, as well as an expiremental Ruby 1.8.3 core
26
+ implementation (see the Suby homepage). We continue to touch up the {RCR}[rcr.html]
27
+ but on the whole it is now complete.
28
+
29
+ Please read {Cut-based AOP for Ruby RCR}[rcr.html].
30
+
31
+ This Cuts library comes by way of {Ruby Facets}[http://rubyworks.github.com/facets],
32
+ where the implementation was orginally housed. Becuase of it's expiremental nature,
33
+ it was deemd best to move it into it's own project as part of the ongoing work to
34
+ make Facets a rock solid library. Despite being expiremental, this implementation
35
+ does pass it's unit test. However, it has had litte trial in integrated tests.
36
+ It will be interesting to see if this library, as it matures, can prove robust
37
+ enough for production use. In either case, clearly it would be preferable to have
38
+ a Ruby-core implementation instead, but that potential is completely in other
39
+ persons hands.
40
+
41
+
42
+ == Usage
43
+
44
+ Here is a quick and dirty example:
45
+
46
+ require 'cuts'
47
+
48
+ class C
49
+ def f ; "f" ; end
50
+ end
51
+
52
+ cut :G < C do
53
+ def f; '<'+super+'>' ; end
54
+ end
55
+
56
+ c = C.new
57
+
58
+ c.f #=> "&lt;f&gt;"
59
+
60
+
61
+ For detailed usage documentation, please refer to the {API Documentation}[http://rubydoc.info/gems/cuts].
62
+
63
+
64
+ == Install
65
+
66
+ Install via RubyGems:
67
+
68
+ $ gem install cuts
69
+
70
+
71
+ == Special Thanks
72
+
73
+ Special thanks to Peter Van Broekhoven. The man is a genius!
74
+
75
+
76
+ == Legal
77
+
78
+ (FreeBSD License)
79
+
80
+ Cuts, Copyright (c) 2007 Thomas Sawyer & Peter Van Broekhoven
81
+
82
+ See NOTICE.rdoc for details.
@@ -1,22 +1,11 @@
1
- # TITLE:
2
- #
3
- # Aspect Oriented Programming for Ruby
4
- #
5
- # SUMMARY:
6
- #
7
- #
8
- # AUTHORS:
9
- #
10
- # - Thomas Sawyer
11
- #
12
- # NOTES:
13
- #
14
- # - Can JointPoint and Target be the same class?
15
-
16
1
  require 'cuts/cut'
17
2
 
18
- #
3
+ require 'pp'
19
4
 
5
+ # TODO: Can JointPoint and Target be the same class?
6
+
7
+ # Aspect Oriented Programming for Ruby using Cuts.
8
+ #
20
9
  class Aspect < Module
21
10
 
22
11
  def initialize(&block)
@@ -104,23 +93,31 @@ end
104
93
 
105
94
 
106
95
  def cross_cut(klass)
96
+
107
97
  Cut.new(klass) do
108
- define_method :__base__ do klass end
109
98
 
110
- def advices; @advices ||= {}; end
99
+ define_method :__base__ do
100
+ klass
101
+ end
102
+
103
+ def advices
104
+ @advices ||= {}
105
+ end
111
106
 
112
107
  def self.extended(obj)
113
108
  base = obj.class #__base__
114
109
 
115
- methods = obj.methods + obj.private_methods - ['advices']
116
-
117
- methods.each do |sym|
110
+ # use string for 1.9-, and symbol for 1.9+
111
+ methods = obj.methods +
112
+ obj.public_methods +
113
+ obj.protected_methods +
114
+ obj.private_methods -
115
+ [:advices, 'advices']
118
116
 
117
+ methods.uniq.each do |sym|
119
118
  #meth = obj.method(sym)
120
-
121
- define_method(sym) do |*args| #, &blk| # TODO imporove interface mirroring
119
+ define_method(sym) do |*args, &blk|
122
120
  jp = Joinpoint.new(self, base, sym, *args) #, &blk)
123
-
124
121
  # calculate advices on first use.
125
122
  unless advices[sym]
126
123
  advices[sym] = []
@@ -136,20 +133,17 @@ def cross_cut(klass)
136
133
  end
137
134
 
138
135
  if advices[sym].empty?
139
- super
136
+ super(*args, &blk)
140
137
  else
141
138
  target = jp #Target.new(self, sym, *args, &blk) # Target == JoinPoint ?
142
139
  advices[sym].each do |(aspect, advice)|
143
140
  target = Target.new(aspect, advice, target)
144
141
  end
145
- target.super
142
+ target.call #super
146
143
  end
147
-
148
- end
149
-
150
- end
151
-
152
- end
144
+ end #define_method
145
+ end #methods
146
+ end #def
153
147
 
154
148
  end
155
149
 
@@ -1,7 +1,8 @@
1
- require 'test/unit'
1
+ require 'microtest'
2
+ require 'ae'
2
3
  require 'cuts'
3
4
 
4
- class TestAop < Test::Unit::TestCase
5
+ class AOPTest < MicroTest::TestCase
5
6
 
6
7
  class X
7
8
  def x; "x"; end
@@ -24,26 +25,27 @@ class TestAop < Test::Unit::TestCase
24
25
  end
25
26
 
26
27
  def test_class
27
- assert_equal(X, @x1.class)
28
+ @x1.class.assert == X
28
29
  end
29
30
 
30
31
  def test_public_methods
31
32
  meths = @x1.public_methods(false)
32
- assert(meths.include?("y"))
33
- assert(meths.include?("q"))
34
- assert(meths.include?("x"))
33
+ meths = meths.map{ |m| m.to_s }
34
+ meths.assert.include?("y")
35
+ meths.assert.include?("q")
36
+ meths.assert.include?("x")
35
37
  end
36
38
 
37
39
  def test_x
38
- assert_equal("{x}", @x1.x)
40
+ @x1.x.assert == "{x}"
39
41
  end
40
42
 
41
43
  def test_y
42
- assert_equal("y", @x1.y)
44
+ @x1.y.assert == "y"
43
45
  end
44
46
 
45
47
  def test_q
46
- assert_equal("<{x}>", @x1.q)
48
+ @x1.q.assert == "<{x}>"
47
49
  end
48
50
 
49
51
  end
@@ -1,7 +1,9 @@
1
- require 'test/unit'
1
+ require 'microtest'
2
+ require 'ae'
2
3
  require 'cuts'
3
4
 
4
- class TestCut < Test::Unit::TestCase
5
+ #
6
+ class TestCutNew < MicroTest::TestCase
5
7
 
6
8
  class X
7
9
  def x; "x"; end
@@ -12,13 +14,14 @@ class TestCut < Test::Unit::TestCase
12
14
  end
13
15
 
14
16
  def test_method_is_wrapped_by_advice
15
- o = X.new
16
- assert_equal("{x}", o.x)
17
+ o = X.new
18
+ o.x.assert == "{x}"
17
19
  end
18
20
 
19
21
  end
20
22
 
21
- class TestCut1 < Test::Unit::TestCase
23
+ #
24
+ class TestLiteralSyntax < MicroTest::TestCase
22
25
 
23
26
  class F
24
27
  def f ; "f" ; end
@@ -31,20 +34,19 @@ class TestCut1 < Test::Unit::TestCase
31
34
 
32
35
  def test_1_01
33
36
  f = F.new
34
- assert_equal( "<f>", f.f )
35
- assert_equal( F, f.class )
37
+ f.f.assert == "<f>"
38
+ f.class.assert == F
36
39
  end
37
40
 
38
41
  def test_1_02
39
42
  assert(G)
40
- assert_equal( "TestCut1::G", G.name )
43
+ G.name.assert == "TestLiteralSyntax::G"
41
44
  end
42
45
 
43
46
  end
44
47
 
45
48
  # Test multiple cuts.
46
-
47
- class TestCut2 < Test::Unit::TestCase
49
+ class TestMultipleCuts < MicroTest::TestCase
48
50
 
49
51
  class F
50
52
  def f ; "f" ; end
@@ -61,24 +63,24 @@ class TestCut2 < Test::Unit::TestCase
61
63
  end
62
64
 
63
65
  #def test_2_01
64
- # assert_equal( [Q, G], F.cuts )
65
- # assert_equal( [Q, G], F.predecessors )
66
+ # F.cuts.assert == [Q, G]
67
+ # F.predecessors.assert == [Q, G]
66
68
  #end
67
69
 
68
70
  def test_2_02
69
71
  f = F.new
70
- assert_equal( F, f.class )
71
- assert_equal( "[<f>]", f.f )
72
+ f.class.assert == F
73
+ f.f.assert == "[<f>]"
72
74
  end
73
75
 
74
76
  def test_2_03
75
77
  assert(G)
76
- assert_equal( "TestCut2::G", G.name )
78
+ G.name.assert == "TestMultipleCuts::G"
77
79
  end
78
80
 
79
81
  def test_2_04
80
82
  assert(Q)
81
- assert_equal( "TestCut2::Q", Q.name )
83
+ Q.name.assert == "TestMultipleCuts::Q"
82
84
  end
83
85
 
84
86
  end
metadata CHANGED
@@ -1,86 +1,96 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: cuts
3
- version: !ruby/object:Gem::Version
4
- version: 1.0.0
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ prerelease:
5
6
  platform: ruby
6
- authors:
7
- - tigerops-community@rubyforge.org
7
+ authors:
8
+ - Thomas Sawyer
9
+ - Peter Vanbroekhoven
8
10
  autorequire:
9
11
  bindir: bin
10
12
  cert_chain: []
11
-
12
- date: 2009-07-04 00:00:00 -04:00
13
- default_executable:
14
- dependencies: []
15
-
16
- description: |-
17
- Cuts is an expiremental implementation of cut-based
18
- AOP for Ruby written in pure Ruby.
19
- email:
13
+ date: 2011-10-27 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: detroit
17
+ requirement: &18946520 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: *18946520
26
+ - !ruby/object:Gem::Dependency
27
+ name: microtest
28
+ requirement: &18945920 !ruby/object:Gem::Requirement
29
+ none: false
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: *18945920
37
+ - !ruby/object:Gem::Dependency
38
+ name: ae
39
+ requirement: &18945380 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *18945380
48
+ description: Cuts is an expiremental implementation of cut-based AOP for Ruby written
49
+ in pure Ruby.
50
+ email:
51
+ - transfire@gmail.com
20
52
  executables: []
21
-
22
53
  extensions: []
23
-
24
- extra_rdoc_files:
25
- - README
26
- - Rakefile
27
- - MANIFEST
28
- - RELEASE
29
- - LICENSE
30
- - HISTORY
31
- files:
32
- - Rakefile
33
- - RELEASE
34
- - LICENSE
35
- - README
36
- - HISTORY
37
- - lib/cuts.rb
54
+ extra_rdoc_files:
55
+ - HISTORY.rdoc
56
+ - README.rdoc
57
+ - NOTICE.rdoc
58
+ - RCR.textile
59
+ files:
60
+ - .ruby
38
61
  - lib/cuts/aop.rb
39
62
  - lib/cuts/cut.rb
40
- - meta/created
41
- - meta/homepage
42
- - meta/summary
43
- - meta/abstract
44
- - meta/package
45
- - meta/version
46
- - meta/license
47
- - meta/project
48
- - meta/contact
49
- - test/test_cut.rb
63
+ - lib/cuts.rb
50
64
  - test/test_aop.rb
51
- - MANIFEST
52
- has_rdoc: true
53
- homepage: http://death.rubyforge.org
54
- licenses: []
55
-
65
+ - test/test_cut.rb
66
+ - HISTORY.rdoc
67
+ - README.rdoc
68
+ - NOTICE.rdoc
69
+ - RCR.textile
70
+ homepage: http://rubyworks.github.com/cuts
71
+ licenses:
72
+ - BSD-2-Clause
73
+ - BSD-2-Clause
56
74
  post_install_message:
57
- rdoc_options:
58
- - --inline-source
59
- - --title
60
- - cuts api
61
- - --main
62
- - README
63
- require_paths:
75
+ rdoc_options: []
76
+ require_paths:
64
77
  - lib
65
- required_ruby_version: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- version: "0"
70
- version:
71
- required_rubygems_version: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: "0"
76
- version:
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
77
90
  requirements: []
78
-
79
- rubyforge_project: death
80
- rubygems_version: 1.3.4
91
+ rubyforge_project:
92
+ rubygems_version: 1.8.10
81
93
  signing_key:
82
94
  specification_version: 3
83
- summary: Cuts is an expiremental implementation of cut-based
84
- test_files:
85
- - test/test_cut.rb
86
- - test/test_aop.rb
95
+ summary: Cut-based AOP for Ruby
96
+ test_files: []