aspector 0.10.1 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.10.1
1
+ 0.11.0
data/aspector.gemspec CHANGED
@@ -4,14 +4,14 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = "aspector"
8
- s.version = "0.10.1"
7
+ s.name = %q{aspector}
8
+ s.version = "0.11.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Guoliang Cao"]
12
- s.date = "2012-03-20"
13
- s.description = ""
14
- s.email = "gcao99@gmail.com"
12
+ s.date = %q{2012-04-15}
13
+ s.description = %q{}
14
+ s.email = %q{gcao99@gmail.com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE.txt",
17
17
  "README.rdoc"
@@ -46,6 +46,7 @@ Gem::Specification.new do |s|
46
46
  "lib/aspector/base_class_methods.rb",
47
47
  "lib/aspector/deferred_logic.rb",
48
48
  "lib/aspector/deferred_option.rb",
49
+ "lib/aspector/logger.rb",
49
50
  "lib/aspector/method_matcher.rb",
50
51
  "lib/aspector/module_extension.rb",
51
52
  "lib/aspector/object_extension.rb",
@@ -55,6 +56,7 @@ Gem::Specification.new do |s|
55
56
  "performance-tests/before_test.rb",
56
57
  "performance-tests/combined_test.rb",
57
58
  "performance-tests/method_invocation_test.rb",
59
+ "performance-tests/raw_test.rb",
58
60
  "performance-tests/test_helper.rb",
59
61
  "spec/functional/advices_on_private_methods_spec.rb",
60
62
  "spec/functional/aspect_on_eigen_class_spec.rb",
@@ -70,13 +72,14 @@ Gem::Specification.new do |s|
70
72
  "spec/unit/base_spec.rb",
71
73
  "spec/unit/before_spec.rb",
72
74
  "spec/unit/deferred_logic_spec.rb",
73
- "spec/unit/method_matcher_spec.rb"
75
+ "spec/unit/method_matcher_spec.rb",
76
+ "spec/unit/raw_spec.rb"
74
77
  ]
75
- s.homepage = "http://github.com/gcao/aspector"
78
+ s.homepage = %q{http://github.com/gcao/aspector}
76
79
  s.licenses = ["MIT"]
77
80
  s.require_paths = ["lib"]
78
- s.rubygems_version = "1.8.18"
79
- s.summary = "Aspect Oriented Ruby Programming"
81
+ s.rubygems_version = %q{1.6.2}
82
+ s.summary = %q{Aspect Oriented Ruby Programming}
80
83
 
81
84
  if s.respond_to? :specification_version then
82
85
  s.specification_version = 3
@@ -13,16 +13,16 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
13
  require 'aspector'
14
14
 
15
15
  class ActiveRecordHooks < Aspector::Base
16
- aspect = self
16
+ logger.level = Aspector::Logger::TRACE
17
17
 
18
18
  default :private_methods => true
19
19
 
20
20
  before :initialize do
21
- puts "#{aspect}: before creating #{self.class.name} instance"
21
+ puts "Before creating #{self.class.name} instance"
22
22
  end
23
23
 
24
24
  before :save do
25
- puts "#{aspect}: before saving"
25
+ puts "Before saving #{self.class.name} instance"
26
26
  end
27
27
  end
28
28
 
@@ -32,4 +32,3 @@ ActiveRecordHooks.apply(A)
32
32
 
33
33
  a = A.new
34
34
  a.save
35
-
@@ -46,7 +46,7 @@ require 'aspector'
46
46
  class CacheAspect < Aspector::Base
47
47
  default :ttl => 60
48
48
 
49
- around options[:method], :aspect_arg => true, :method_arg => true do |aspect, method, proxy, &block|
49
+ around :aspect_arg => true, :method_arg => true do |aspect, method, proxy, &block|
50
50
  key = method
51
51
  ttl = aspect.options[:ttl]
52
52
 
@@ -59,8 +59,8 @@ end
59
59
 
60
60
  ##############################
61
61
 
62
- CacheAspect.apply A, :method => :test, :ttl => 2 # 2 seconds
63
- CacheAspect.apply A, :method => :test2
62
+ CacheAspect.apply "A#test", :ttl => 2 # 2 seconds
63
+ CacheAspect.apply "A#test2"
64
64
 
65
65
  a = A.new
66
66
 
@@ -22,13 +22,13 @@ class ExceptionHandler < Aspector::Base
22
22
  end
23
23
  end
24
24
 
25
- around options[:method], :handle_exception
25
+ around :handle_exception
26
26
 
27
27
  end
28
28
 
29
29
  ##############################
30
30
 
31
- ExceptionHandler.apply(A, :method => :test)
31
+ ExceptionHandler.apply "A#test"
32
32
 
33
33
  a = A.new
34
34
  a.test 'good'
@@ -28,13 +28,13 @@ class RetryAspect < Aspector::Base
28
28
  end
29
29
  end
30
30
 
31
- around options[:method], :retry_this
31
+ around :retry_this
32
32
 
33
33
  end
34
34
 
35
35
  ##############################
36
36
 
37
- RetryAspect.apply(A, :method => :test)
37
+ RetryAspect.apply "A#test"
38
38
 
39
39
  a = A.new
40
40
  a.test
@@ -4,8 +4,10 @@ module Aspector
4
4
  BEFORE = 1
5
5
  AFTER = 2
6
6
  AROUND = 3
7
+ RAW = 4
7
8
 
8
9
  attr_reader :type, :method_matcher, :options, :advice_block
10
+ attr_accessor :index
9
11
 
10
12
  def initialize parent, type, method_matcher, with_method, options = {}, &block
11
13
  @parent = parent
@@ -31,6 +33,10 @@ module Aspector
31
33
  not @except.match?(method)
32
34
  end
33
35
 
36
+ def raw?
37
+ type == RAW
38
+ end
39
+
34
40
  def before?
35
41
  type == BEFORE
36
42
  end
@@ -52,19 +58,21 @@ module Aspector
52
58
  when BEFORE then @options[:skip_if_false] ? "BEFORE_FILTER" : "BEFORE"
53
59
  when AFTER then "AFTER"
54
60
  when AROUND then "AROUND"
61
+ when RAW then "RAW"
55
62
  else "UNKNOWN?!"
56
63
  end
57
64
  end
58
65
 
59
66
  def to_s
60
- s = type_name
67
+ s = "<advice " << index.to_s << ">: "
68
+ s << type_name
61
69
  s << " [" << @method_matcher.to_s << "] DO "
62
- s << @with_method.to_s
63
- s << " WITH OPTIONS "
64
- @options.each do |key, value|
65
- next if key == :skip_if_false
66
- s << key.to_s << ":" << value.to_s << " "
70
+ if @with_method
71
+ s << @with_method.to_s
72
+ else
73
+ s << "stuff in block"
67
74
  end
75
+ s << " WITH OPTIONS " << @options.inspect
68
76
  s
69
77
  end
70
78
 
@@ -12,6 +12,7 @@ module Aspector
12
12
  BEFORE_FILTER = new Aspector::Advice::BEFORE, nil, :skip_if_false => true
13
13
  AFTER = new Aspector::Advice::AFTER, { :result_arg => true }, nil
14
14
  AROUND = new Aspector::Advice::AROUND, nil, nil
15
+ RAW = new Aspector::Advice::RAW, nil, nil
15
16
  end
16
17
  end
17
18
 
data/lib/aspector/base.rb CHANGED
@@ -4,7 +4,10 @@ module Aspector
4
4
  class Base
5
5
 
6
6
  attr :aop_options
7
- alias :options :aop_options
7
+ alias options aop_options
8
+
9
+ attr :aop_target
10
+ alias target aop_target
8
11
 
9
12
  attr :aop_wrapped_methods
10
13
 
@@ -51,7 +54,7 @@ module Aspector
51
54
 
52
55
  aop_disabled?
53
56
  end
54
- alias reset_disabled :aop_reset_disabled
57
+ alias reset_disabled aop_reset_disabled
55
58
 
56
59
  def aop_disabled?
57
60
  end
@@ -60,10 +63,15 @@ module Aspector
60
63
  aop_disabled?
61
64
  end
62
65
 
66
+ def aop_logger
67
+ @aop_logger ||= Logger.new(self, self.class.logger.level)
68
+ end
69
+ alias logger aop_logger
70
+
63
71
  def aop_advices
64
72
  self.class.aop_advices
65
73
  end
66
- alias :advices :aop_advices
74
+ alias advices aop_advices
67
75
 
68
76
  def aop_apply
69
77
  before_apply
@@ -74,7 +82,7 @@ module Aspector
74
82
  aop_add_method_hooks unless @aop_options[:old_methods_only]
75
83
  after_apply
76
84
  end
77
- alias :apply :aop_apply
85
+ alias apply aop_apply
78
86
 
79
87
  def aop_apply_to_methods
80
88
  advices = aop_advices
@@ -112,6 +120,7 @@ module Aspector
112
120
  advices = aop_filter_advices advices, method
113
121
  return if advices.empty?
114
122
 
123
+ aop_logger.log Logger::APPLY_TO_METHOD, method
115
124
  before_apply_to_method method, advices
116
125
 
117
126
  scope ||=
@@ -173,6 +182,7 @@ module Aspector
173
182
 
174
183
  def aop_define_methods_for_advice_blocks
175
184
  aop_advices.each do |advice|
185
+ next if advice.raw?
176
186
  next unless advice.advice_block
177
187
  @aop_context.send :define_method, advice.with_method, advice.advice_block
178
188
  @aop_context.send :private, advice.with_method
@@ -224,9 +234,24 @@ module Aspector
224
234
  end
225
235
 
226
236
  def aop_recreate_method method, advices, scope
227
- @aop_wrapped_methods[method] = @aop_context.instance_method(method)
228
237
  @aop_context.instance_variable_set(:@aop_creating_method, true)
229
238
 
239
+ raw_advices = advices.select {|advice| advice.raw? }
240
+
241
+ if raw_advices.size > 0
242
+ raw_advices.each do |advice|
243
+ if @aop_target.is_a? Module and not @aop_options[:class_methods]
244
+ @aop_target.class_exec method, self, &advice.advice_block
245
+ else
246
+ @aop_target.instance_exec method, self, &advice.advice_block
247
+ end
248
+ end
249
+
250
+ return if raw_advices.size == advices.size
251
+ end
252
+
253
+ @aop_wrapped_methods[method] = @aop_context.instance_method(method)
254
+
230
255
  before_advices = advices.select {|advice| advice.before? }
231
256
  after_advices = advices.select {|advice| advice.after? }
232
257
  around_advices = advices.select {|advice| advice.around? }
@@ -240,79 +265,137 @@ module Aspector
240
265
 
241
266
  @aop_context.send scope, method if scope != :public
242
267
  ensure
243
- @aop_context.instance_variable_set(:@aop_creating_method, nil)
268
+ @aop_context.send :remove_instance_variable, :@aop_creating_method
244
269
  end
245
270
 
246
271
  def aop_recreate_method_with_advices method, before_advices, after_advices, around_advice, is_outermost = false
247
272
  aspect = self
248
273
 
249
274
  code = METHOD_TEMPLATE.result(binding)
250
- #puts code
275
+ aspect.aop_logger.log Logger::GENERATE_CODE, method, code
251
276
  @aop_context.class_eval code, __FILE__, __LINE__ + 4
252
277
  end
253
278
 
254
- METHOD_TEMPLATE = ERB.new <<-CODE
255
- orig_method = aspect.aop_wrapped_methods['<%= method %>']
279
+ METHOD_TEMPLATE = ERB.new <<-CODE, nil, "%<>"
256
280
 
257
- <% if around_advice %>
281
+ orig_method = aspect.aop_wrapped_methods['<%= method %>']
282
+ % if around_advice
258
283
  wrapped_method = instance_method(:<%= method %>)
259
- <% end %>
284
+ % end
260
285
 
261
286
  define_method :<%= method %> do |*args, &block|
262
- return orig_method.bind(self).call(*args, &block) if aspect.aop_disabled?
287
+ % if aop_logger.visible?(Logger::TRACE)
288
+ aspect.aop_logger.log_method_call '<%= method %>', Aspector::Logger::ENTER_GENERATED_METHOD
289
+ % end
290
+
291
+ if aspect.aop_disabled?
292
+ % if aop_logger.visible?(Logger::TRACE)
293
+ aspect.aop_logger.log_method_call '<%= method %>', Aspector::Logger::EXIT_BECAUSE_DISABLED
294
+ % end
295
+ return orig_method.bind(self).call(*args, &block)
296
+ end
263
297
 
264
- <% if is_outermost %>
265
- catch(:aop_returns) do
266
- <% end %>
298
+ % if is_outermost
299
+ result = catch(:aop_returns) do
300
+ % end
267
301
 
302
+ % unless before_advices.empty?
268
303
  # Before advices
269
- <% before_advices.each do |advice| %>
304
+ % end
305
+ % before_advices.each do |advice|
306
+ % if aop_logger.visible?(Logger::TRACE)
307
+ aspect.aop_logger.log_method_call '<%= method %>', Aspector::Logger::BEFORE_INVOKE_ADVICE, '<advice <%= advice.index %>>'
308
+ % end
270
309
  result = <%= advice.with_method %> <%
271
310
  if advice.options[:aspect_arg] %>aspect, <% end %><%
272
311
  if advice.options[:method_arg] %>'<%= method %>', <% end
273
312
  %>*args
313
+ % if aop_logger.visible?(Logger::TRACE)
314
+ aspect.aop_logger.log_method_call '<%= method %>', Aspector::Logger::AFTER_INVOKE_ADVICE, '<advice <%= advice.index %>>'
315
+ % end
316
+ % if advice.options[:skip_if_false]
317
+ unless result
318
+ % if aop_logger.visible?(Logger::TRACE)
319
+ aspect.aop_logger.log_method_call '<%= method %>', Aspector::Logger::EXIT_FROM_BEFORE_FILTER, '<advice <%= advice.index %>>'
320
+ % end
321
+ return
322
+ end
323
+ % end
324
+ % end
274
325
 
275
- <% if advice.options[:skip_if_false] %>
276
- return unless result
277
- <% end
278
- end
279
- %>
280
-
281
- <% if around_advice %>
326
+ % if around_advice
282
327
  # Around advice
328
+ % if aop_logger.visible?(Logger::TRACE)
329
+ aspect.aop_logger.log_method_call '<%= method %>', Aspector::Logger::BEFORE_INVOKE_ADVICE, '<advice <%= around_advice.index %>>'
330
+ % end
331
+ % if aop_logger.visible?(Logger::TRACE)
332
+ proxy = lambda do |*args, &block|
333
+ aspect.aop_logger.log_method_call '<%= method %>', Aspector::Logger::BEFORE_INVOKE_PROXY
334
+ res = wrapped_method.bind(self).call *args, &block
335
+ aspect.aop_logger.log_method_call '<%= method %>', Aspector::Logger::AFTER_INVOKE_PROXY
336
+ res
337
+ end
338
+ result = <%= around_advice.with_method %> <%
339
+ if around_advice.options[:aspect_arg] %>aspect, <% end %><%
340
+ if around_advice.options[:method_arg] %>'<%= method %>', <% end
341
+ %>proxy, *args, &block
342
+ % else
283
343
  result = <%= around_advice.with_method %> <%
284
344
  if around_advice.options[:aspect_arg] %>aspect, <% end %><%
285
345
  if around_advice.options[:method_arg] %>'<%= method %>', <% end
286
346
  %>wrapped_method.bind(self), *args, &block
287
- <% else %>
347
+ % end
348
+ % if aop_logger.visible?(Logger::TRACE)
349
+ aspect.aop_logger.log_method_call '<%= method %>', Aspector::Logger::AFTER_INVOKE_ADVICE, '<advice <%= around_advice.index %>>'
350
+ % end
351
+
352
+ % else
353
+
288
354
  # Invoke original method
355
+ % if aop_logger.visible?(Logger::TRACE)
356
+ aspect.aop_logger.log_method_call '<%= method %>', Aspector::Logger::BEFORE_WRAPPED_METHOD
357
+ % end
289
358
  result = orig_method.bind(self).call *args, &block
290
- <% end %>
359
+ % if aop_logger.visible?(Logger::TRACE)
360
+ aspect.aop_logger.log_method_call '<%= method %>', Aspector::Logger::AFTER_WRAPPED_METHOD
361
+ % end
291
362
 
363
+ % end
364
+
365
+ % unless after_advices.empty?
292
366
  # After advices
293
- <% unless after_advices.empty?
294
- after_advices.each do |advice|
295
- if advice.options[:result_arg]
296
- %>
367
+ % after_advices.each do |advice|
368
+ % if aop_logger.visible?(Logger::TRACE)
369
+ aspect.aop_logger.log_method_call '<%= method %>', Aspector::Logger::BEFORE_INVOKE_ADVICE, '<advice <%= advice.index %>>'
370
+ % end
371
+ % if advice.options[:result_arg]
297
372
  result = <%= advice.with_method %> <%
298
373
  if advice.options[:aspect_arg] %>aspect, <% end %><%
299
374
  if advice.options[:method_arg] %>'<%= method %>', <% end %><%
300
375
  if advice.options[:result_arg] %>result, <% end
301
376
  %>*args
302
- <% else %>
377
+ % else
303
378
  <%= advice.with_method %> <%
304
379
  if advice.options[:aspect_arg] %>aspect, <% end %><%
305
380
  if advice.options[:method_arg] %>'<%= method %>', <% end
306
381
  %>*args
307
- <% end
308
- end
309
- %>
382
+ % end
383
+ % if aop_logger.visible?(Logger::TRACE)
384
+ aspect.aop_logger.log_method_call '<%= method %>', Aspector::Logger::AFTER_INVOKE_ADVICE, '<advice <%= advice.index %>>'
385
+ % end
386
+ % end
387
+ % end
388
+
389
+ % if is_outermost
310
390
  result
311
- <% end %>
312
391
 
313
- <% if is_outermost %>
314
- end
315
- <% end %>
392
+ end # end of catch
393
+ % end
394
+
395
+ % if aop_logger.visible?(Logger::TRACE)
396
+ aspect.aop_logger.log_method_call '<%= method %>', Aspector::Logger::EXIT_GENERATED_METHOD
397
+ % end
398
+ result
316
399
  end
317
400
  CODE
318
401
 
@@ -4,33 +4,41 @@ module Aspector
4
4
  ::Aspector::Base.extend(self)
5
5
 
6
6
  def aop_enable
7
+ aop_logger.log Logger::ENABLE_ASPECT
7
8
  send :define_method, :aop_disabled? do
8
9
  end
9
10
 
10
11
  nil
11
12
  end
12
- alias :enable :aop_enable
13
+ alias enable aop_enable
13
14
 
14
15
  def aop_disable
16
+ aop_logger.log Logger::DISABLE_ASPECT
15
17
  send :define_method, :aop_disabled? do
16
18
  true
17
19
  end
18
20
 
19
21
  nil
20
22
  end
21
- alias :disable :aop_disable
23
+ alias disable aop_disable
24
+
25
+ def aop_logger
26
+ @aop_logger ||= Logger.new(self)
27
+ end
28
+ alias logger aop_logger
22
29
 
23
30
  def aop_advices
24
31
  @aop_advices ||= []
25
32
  end
26
- alias :advices :aop_advices
33
+ alias advices aop_advices
27
34
 
28
35
  def aop_default_options
29
36
  @aop_default_options ||= {}
30
37
  end
31
- alias :default_options :aop_default_options
38
+ alias default_options aop_default_options
32
39
 
33
40
  def aop_apply target, options = {}
41
+ aop_logger.log Logger::APPLY, target, options.inspect
34
42
  # Handle 'Klass#method' and 'Klass.method' shortcut
35
43
  if target.is_a? String
36
44
  if target.index('.')
@@ -48,7 +56,7 @@ module Aspector
48
56
  aspect_instance.send :aop_apply
49
57
  aspect_instance
50
58
  end
51
- alias :apply :aop_apply
59
+ alias apply aop_apply
52
60
 
53
61
  def aop_default options
54
62
  if @aop_default_options
@@ -57,27 +65,47 @@ module Aspector
57
65
  @aop_default_options = options
58
66
  end
59
67
  end
60
- alias :default :aop_default
68
+ alias default aop_default
61
69
 
62
70
  def aop_before *methods, &block
63
- aop_advices << aop_create_advice(Aspector::AdviceMetadata::BEFORE, self, methods, &block)
71
+ aop_advices << advice = aop_create_advice(Aspector::AdviceMetadata::BEFORE, self, methods, &block)
72
+ advice.index = aop_advices.size
73
+ aop_logger.log Logger::DEFINE_ADVICE, advice
74
+ advice
64
75
  end
65
- alias :before :aop_before
76
+ alias before aop_before
66
77
 
67
78
  def aop_before_filter *methods, &block
68
- aop_advices << aop_create_advice(Aspector::AdviceMetadata::BEFORE_FILTER, self, methods, &block)
79
+ aop_advices << advice = aop_create_advice(Aspector::AdviceMetadata::BEFORE_FILTER, self, methods, &block)
80
+ advice.index = aop_advices.size
81
+ aop_logger.log Logger::DEFINE_ADVICE, advice
82
+ advice
69
83
  end
70
- alias :before_filter :aop_before_filter
84
+ alias before_filter aop_before_filter
71
85
 
72
86
  def aop_after *methods, &block
73
- aop_advices << aop_create_advice(Aspector::AdviceMetadata::AFTER, self, methods, &block)
87
+ aop_advices << advice = aop_create_advice(Aspector::AdviceMetadata::AFTER, self, methods, &block)
88
+ advice.index = aop_advices.size
89
+ aop_logger.log Logger::DEFINE_ADVICE, advice
90
+ advice
74
91
  end
75
- alias :after :aop_after
92
+ alias after aop_after
76
93
 
77
94
  def aop_around *methods, &block
78
- aop_advices << aop_create_advice(Aspector::AdviceMetadata::AROUND, self, methods, &block)
95
+ aop_advices << advice = aop_create_advice(Aspector::AdviceMetadata::AROUND, self, methods, &block)
96
+ advice.index = aop_advices.size
97
+ aop_logger.log Logger::DEFINE_ADVICE, advice
98
+ advice
99
+ end
100
+ alias around aop_around
101
+
102
+ def aop_raw *methods, &block
103
+ aop_advices << advice = aop_create_advice(Aspector::AdviceMetadata::RAW, self, methods, &block)
104
+ advice.index = aop_advices.size
105
+ aop_logger.log Logger::DEFINE_ADVICE, advice
106
+ advice
79
107
  end
80
- alias :around :aop_around
108
+ alias raw aop_raw
81
109
 
82
110
  def aop_target code = nil, &block
83
111
  return unless code or block_given?
@@ -86,12 +114,12 @@ module Aspector
86
114
  aop_deferred_logics << logic
87
115
  logic
88
116
  end
89
- alias :target :aop_target
117
+ alias target aop_target
90
118
 
91
119
  def aop_options
92
120
  DeferredOption.new
93
121
  end
94
- alias :options :aop_options
122
+ alias options aop_options
95
123
 
96
124
  private
97
125
 
@@ -111,7 +139,12 @@ module Aspector
111
139
  methods[i] = methods[i].to_s if methods[i].is_a? Symbol
112
140
  end
113
141
 
114
- with_method = methods.pop unless block_given?
142
+ if meta_data.advice_type == Aspector::Advice::RAW
143
+ raise "Bad raw advice - code block is required" unless block_given?
144
+ with_method = nil
145
+ else
146
+ with_method = methods.pop unless block_given?
147
+ end
115
148
 
116
149
  methods << aop_options[:method] << aop_options[:methods] if methods.empty?
117
150
 
@@ -8,5 +8,9 @@ module Aspector
8
8
  self
9
9
  end
10
10
 
11
+ def inspect
12
+ "options[:#{key}]"
13
+ end
11
14
  end
12
15
  end
16
+
@@ -0,0 +1,110 @@
1
+ module Aspector
2
+ class Logger
3
+ # Log levels
4
+ ERROR = 50
5
+ WARN = 40
6
+ INFO = 30
7
+ DEBUG = 20
8
+ TRACE = 10
9
+
10
+ DEFAULT_VISIBLE_LEVEL = INFO
11
+
12
+ # Actions
13
+ DEFINE_ADVICE = %W"define-advice"
14
+ APPLY = %W"apply"
15
+ APPLY_TO_METHOD = %W"apply-to-method #{DEBUG}"
16
+ ENABLE_ASPECT = %W"enable-aspect"
17
+ DISABLE_ASPECT = %W"disable-aspect"
18
+
19
+ GENERATE_CODE = %W"generate-code #{DEBUG}"
20
+
21
+ ENTER_GENERATED_METHOD = %W"enter-generated-method #{TRACE}"
22
+ EXIT_GENERATED_METHOD = %W"exit--generated-method #{TRACE}"
23
+ EXIT_BECAUSE_DISABLED = %W"exit--because-disabled #{TRACE}"
24
+ BEFORE_INVOKE_ADVICE = %W"before-invoke-advice #{TRACE}"
25
+ AFTER_INVOKE_ADVICE = %W"after--invoke-advice #{TRACE}"
26
+ BEFORE_WRAPPED_METHOD = %W"before-wrapped-method #{TRACE}"
27
+ AFTER_WRAPPED_METHOD = %W"after--wrapped-method #{TRACE}"
28
+ BEFORE_INVOKE_PROXY = %W"before-invoke-proxy #{TRACE}"
29
+ AFTER_INVOKE_PROXY = %W"after--invoke-proxy #{TRACE}"
30
+
31
+ attr_reader :context
32
+ attr_writer :level
33
+
34
+ def initialize context, level = nil
35
+ @context = context
36
+ @level = level
37
+ end
38
+
39
+ def level
40
+ return @level if @level
41
+
42
+ if (level_string = ENV['ASPECTOR_LOG_LEVEL'])
43
+ @level = string_to_level(level_string)
44
+ else
45
+ @level = DEFAULT_VISIBLE_LEVEL
46
+ end
47
+ end
48
+
49
+ def log action_level, *args
50
+ action, level = parse_action_level(action_level)
51
+
52
+ return if self.level > level
53
+
54
+ puts log_prefix(level) << action << " | " << args.join(" | ")
55
+ end
56
+
57
+ def log_method_call method, action_level, *args
58
+ action, level = parse_action_level(action_level)
59
+
60
+ return if self.level > level
61
+
62
+ puts log_prefix(level) << method << " | " << action << " | " << args.join(" | ")
63
+ end
64
+
65
+ def visible? level
66
+ self.level <= level
67
+ end
68
+
69
+ private
70
+
71
+ def parse_action_level action_level
72
+ action = action_level[0]
73
+ level = (action_level[1] || INFO).to_i
74
+ return action, level
75
+ end
76
+
77
+ def log_prefix level
78
+ s = "Aspector | " << level_to_string(level) << " | "
79
+ if context.is_a? Aspector::Base
80
+ s << context.class.to_s << " | " << context.aop_target.to_s << " | "
81
+ else
82
+ s << context.to_s << " | "
83
+ end
84
+ end
85
+
86
+ def level_to_string level
87
+ case level
88
+ when ERROR then "ERROR"
89
+ when WARN then "WARN "
90
+ when INFO then "INFO "
91
+ when DEBUG then "DEBUG"
92
+ when TRACE then "TRACE"
93
+ else level.to_s
94
+ end
95
+ end
96
+
97
+ def string_to_level level_string
98
+ return if level_string.nil? or level_string.strip == ''
99
+
100
+ case level_string.downcase
101
+ when 'error' then ERROR
102
+ when 'warn' then WARN
103
+ when 'info' then INFO
104
+ when 'debug' then DEBUG
105
+ when 'trace' then TRACE
106
+ end
107
+ end
108
+ end
109
+ end
110
+
@@ -19,7 +19,7 @@ module Aspector
19
19
 
20
20
  yield if block_given?
21
21
  ensure
22
- instance_variable_set(aop_applied_flag, nil)
22
+ remove_instance_variable aop_applied_flag
23
23
  end
24
24
  end
25
25
 
@@ -42,7 +42,7 @@ module Aspector
42
42
 
43
43
  yield if block_given?
44
44
  ensure
45
- eigen_class.instance_variable_set(aop_applied_flag, nil)
45
+ eigen_class.send :remove_instance_variable, aop_applied_flag
46
46
  end
47
47
  end
48
48
 
data/lib/aspector.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'aspector/logger'
2
+
1
3
  require 'aspector/object_extension'
2
4
  require 'aspector/module_extension'
3
5
 
@@ -26,14 +26,15 @@ class AroundAspect < Aspector::Base
26
26
  end
27
27
 
28
28
  class RawAspect < Aspector::Base
29
- target do
30
- wrapped_method = instance_method(:test)
31
- define_method :test do |*args, &block|
32
- begin
33
- wrapped_method.bind(self).call *args, &block
34
- rescue => e
35
- end
29
+ raw :test do |method,|
30
+ eval <<-CODE
31
+ alias #{method}_without_aspect #{method}
32
+
33
+ def #{method} *args, &block
34
+ #{method}_without_aspect *args, &block
35
+ rescue => e
36
36
  end
37
+ CODE
37
38
  end
38
39
  end
39
40
 
@@ -0,0 +1,37 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
+
3
+ class RawTest < Test::Unit::TestCase
4
+ include RubyProf::Test
5
+
6
+ class Klass
7
+
8
+ aspector do
9
+
10
+ raw :test do |method, aspect|
11
+ eval <<-CODE
12
+ alias #{method}_without_aspect #{method}
13
+
14
+ define_method :#{method} do
15
+ return #{method}_without_aspect if aspect.disabled?
16
+ before_#{method}
17
+ #{method}_without_aspect
18
+ end
19
+ CODE
20
+ end
21
+
22
+ end
23
+
24
+ def test_no_aspect; end
25
+
26
+ def test; end
27
+
28
+ def before_test; end
29
+ end
30
+
31
+ def test_raw
32
+ o = Klass.new
33
+ o.test_no_aspect
34
+ o.test
35
+ end
36
+ end
37
+
@@ -5,5 +5,5 @@ require 'test/unit'
5
5
  require 'ruby-prof/test'
6
6
  require 'aspector'
7
7
 
8
- RubyProf::Test::PROFILE_OPTIONS[:count ] = 10000
8
+ RubyProf::Test::PROFILE_OPTIONS[:count ] = 200000
9
9
  RubyProf::Test::PROFILE_OPTIONS[:output_dir] = File.dirname(__FILE__) + "/output"
@@ -0,0 +1,53 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe "Raw advices" do
4
+ it "should work" do
5
+ klass = create_test_class
6
+
7
+ aspector(klass) do
8
+ raw :test do
9
+ alias test_without_aspect test
10
+ def test
11
+ value << "raw_before"
12
+ test_without_aspect
13
+ end
14
+ end
15
+ end
16
+
17
+ obj = klass.new
18
+ obj.test
19
+ obj.value.should == %w"raw_before test"
20
+ end
21
+
22
+ it "new methods should work" do
23
+ klass = Class.new do
24
+ aspector do
25
+ raw :test do
26
+ alias test_without_aspect test
27
+ def test
28
+ do_this
29
+ test_without_aspect
30
+ end
31
+ end
32
+ end
33
+
34
+ def value
35
+ @value ||= []
36
+ end
37
+
38
+ def test
39
+ value << "test"
40
+ end
41
+
42
+ def do_this
43
+ value << "do_this"
44
+ end
45
+ end
46
+
47
+ obj = klass.new
48
+ obj.test
49
+ obj.value.should == %w"do_this test"
50
+ end
51
+
52
+ end
53
+
metadata CHANGED
@@ -1,200 +1,202 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: aspector
3
- version: !ruby/object:Gem::Version
4
- version: 0.10.1
3
+ version: !ruby/object:Gem::Version
4
+ hash: 51
5
5
  prerelease:
6
+ segments:
7
+ - 0
8
+ - 11
9
+ - 0
10
+ version: 0.11.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Guoliang Cao
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-03-20 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: rspec
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
22
- type: :development
17
+
18
+ date: 2012-04-15 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
23
22
  prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
23
+ type: :development
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
26
- requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
29
- version: '0'
30
- - !ruby/object:Gem::Dependency
31
- name: jeweler
32
- requirement: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ name: rspec
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ prerelease: false
37
+ type: :development
38
+ requirement: &id002 !ruby/object:Gem::Requirement
33
39
  none: false
34
- requirements:
40
+ requirements:
35
41
  - - ~>
36
- - !ruby/object:Gem::Version
42
+ - !ruby/object:Gem::Version
43
+ hash: 7
44
+ segments:
45
+ - 1
46
+ - 6
47
+ - 4
37
48
  version: 1.6.4
38
- type: :development
49
+ name: jeweler
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
39
52
  prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
53
+ type: :development
54
+ requirement: &id003 !ruby/object:Gem::Requirement
41
55
  none: false
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
45
- version: 1.6.4
46
- - !ruby/object:Gem::Dependency
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
47
63
  name: ruby-prof
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ! '>='
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
- type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
55
66
  prerelease: false
56
- version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
- requirements:
59
- - - ! '>='
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- - !ruby/object:Gem::Dependency
63
- name: guard
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ~>
68
- - !ruby/object:Gem::Version
69
- version: 0.8.4
70
67
  type: :development
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
68
+ requirement: &id004 !ruby/object:Gem::Requirement
73
69
  none: false
74
- requirements:
70
+ requirements:
75
71
  - - ~>
76
- - !ruby/object:Gem::Version
72
+ - !ruby/object:Gem::Version
73
+ hash: 55
74
+ segments:
75
+ - 0
76
+ - 8
77
+ - 4
77
78
  version: 0.8.4
78
- - !ruby/object:Gem::Dependency
79
- name: guard-bundler
80
- requirement: !ruby/object:Gem::Requirement
81
- none: false
82
- requirements:
83
- - - ~>
84
- - !ruby/object:Gem::Version
85
- version: 0.1.3
86
- type: :development
79
+ name: guard
80
+ version_requirements: *id004
81
+ - !ruby/object:Gem::Dependency
87
82
  prerelease: false
88
- version_requirements: !ruby/object:Gem::Requirement
83
+ type: :development
84
+ requirement: &id005 !ruby/object:Gem::Requirement
89
85
  none: false
90
- requirements:
86
+ requirements:
91
87
  - - ~>
92
- - !ruby/object:Gem::Version
88
+ - !ruby/object:Gem::Version
89
+ hash: 29
90
+ segments:
91
+ - 0
92
+ - 1
93
+ - 3
93
94
  version: 0.1.3
94
- - !ruby/object:Gem::Dependency
95
- name: guard-rspec
96
- requirement: !ruby/object:Gem::Requirement
97
- none: false
98
- requirements:
99
- - - ~>
100
- - !ruby/object:Gem::Version
101
- version: 0.5.2
102
- type: :development
95
+ name: guard-bundler
96
+ version_requirements: *id005
97
+ - !ruby/object:Gem::Dependency
103
98
  prerelease: false
104
- version_requirements: !ruby/object:Gem::Requirement
99
+ type: :development
100
+ requirement: &id006 !ruby/object:Gem::Requirement
105
101
  none: false
106
- requirements:
102
+ requirements:
107
103
  - - ~>
108
- - !ruby/object:Gem::Version
104
+ - !ruby/object:Gem::Version
105
+ hash: 15
106
+ segments:
107
+ - 0
108
+ - 5
109
+ - 2
109
110
  version: 0.5.2
110
- - !ruby/object:Gem::Dependency
111
- name: guard-shell
112
- requirement: !ruby/object:Gem::Requirement
113
- none: false
114
- requirements:
115
- - - ~>
116
- - !ruby/object:Gem::Version
117
- version: 0.1.1
118
- type: :development
111
+ name: guard-rspec
112
+ version_requirements: *id006
113
+ - !ruby/object:Gem::Dependency
119
114
  prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
115
+ type: :development
116
+ requirement: &id007 !ruby/object:Gem::Requirement
121
117
  none: false
122
- requirements:
118
+ requirements:
123
119
  - - ~>
124
- - !ruby/object:Gem::Version
120
+ - !ruby/object:Gem::Version
121
+ hash: 25
122
+ segments:
123
+ - 0
124
+ - 1
125
+ - 1
125
126
  version: 0.1.1
126
- - !ruby/object:Gem::Dependency
127
- name: rb-fsevent
128
- requirement: !ruby/object:Gem::Requirement
129
- none: false
130
- requirements:
131
- - - ~>
132
- - !ruby/object:Gem::Version
133
- version: 0.4.3.1
134
- type: :development
127
+ name: guard-shell
128
+ version_requirements: *id007
129
+ - !ruby/object:Gem::Dependency
135
130
  prerelease: false
136
- version_requirements: !ruby/object:Gem::Requirement
131
+ type: :development
132
+ requirement: &id008 !ruby/object:Gem::Requirement
137
133
  none: false
138
- requirements:
134
+ requirements:
139
135
  - - ~>
140
- - !ruby/object:Gem::Version
136
+ - !ruby/object:Gem::Version
137
+ hash: 97
138
+ segments:
139
+ - 0
140
+ - 4
141
+ - 3
142
+ - 1
141
143
  version: 0.4.3.1
142
- - !ruby/object:Gem::Dependency
143
- name: growl
144
- requirement: !ruby/object:Gem::Requirement
144
+ name: rb-fsevent
145
+ version_requirements: *id008
146
+ - !ruby/object:Gem::Dependency
147
+ prerelease: false
148
+ type: :development
149
+ requirement: &id009 !ruby/object:Gem::Requirement
145
150
  none: false
146
- requirements:
151
+ requirements:
147
152
  - - ~>
148
- - !ruby/object:Gem::Version
153
+ - !ruby/object:Gem::Version
154
+ hash: 17
155
+ segments:
156
+ - 1
157
+ - 0
158
+ - 3
149
159
  version: 1.0.3
150
- type: :development
160
+ name: growl
161
+ version_requirements: *id009
162
+ - !ruby/object:Gem::Dependency
151
163
  prerelease: false
152
- version_requirements: !ruby/object:Gem::Requirement
164
+ type: :development
165
+ requirement: &id010 !ruby/object:Gem::Requirement
153
166
  none: false
154
- requirements:
155
- - - ~>
156
- - !ruby/object:Gem::Version
157
- version: 1.0.3
158
- - !ruby/object:Gem::Dependency
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ hash: 3
171
+ segments:
172
+ - 0
173
+ version: "0"
159
174
  name: awesome_print
160
- requirement: !ruby/object:Gem::Requirement
161
- none: false
162
- requirements:
163
- - - ! '>='
164
- - !ruby/object:Gem::Version
165
- version: '0'
166
- type: :development
175
+ version_requirements: *id010
176
+ - !ruby/object:Gem::Dependency
167
177
  prerelease: false
168
- version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
- requirements:
171
- - - ! '>='
172
- - !ruby/object:Gem::Version
173
- version: '0'
174
- - !ruby/object:Gem::Dependency
175
- name: pry
176
- requirement: !ruby/object:Gem::Requirement
177
- none: false
178
- requirements:
179
- - - ! '>='
180
- - !ruby/object:Gem::Version
181
- version: '0'
182
178
  type: :development
183
- prerelease: false
184
- version_requirements: !ruby/object:Gem::Requirement
179
+ requirement: &id011 !ruby/object:Gem::Requirement
185
180
  none: false
186
- requirements:
187
- - - ! '>='
188
- - !ruby/object:Gem::Version
189
- version: '0'
190
- description: ''
181
+ requirements:
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ hash: 3
185
+ segments:
186
+ - 0
187
+ version: "0"
188
+ name: pry
189
+ version_requirements: *id011
190
+ description: ""
191
191
  email: gcao99@gmail.com
192
192
  executables: []
193
+
193
194
  extensions: []
194
- extra_rdoc_files:
195
+
196
+ extra_rdoc_files:
195
197
  - LICENSE.txt
196
198
  - README.rdoc
197
- files:
199
+ files:
198
200
  - .document
199
201
  - .irbrc
200
202
  - .rspec
@@ -224,6 +226,7 @@ files:
224
226
  - lib/aspector/base_class_methods.rb
225
227
  - lib/aspector/deferred_logic.rb
226
228
  - lib/aspector/deferred_option.rb
229
+ - lib/aspector/logger.rb
227
230
  - lib/aspector/method_matcher.rb
228
231
  - lib/aspector/module_extension.rb
229
232
  - lib/aspector/object_extension.rb
@@ -233,6 +236,7 @@ files:
233
236
  - performance-tests/before_test.rb
234
237
  - performance-tests/combined_test.rb
235
238
  - performance-tests/method_invocation_test.rb
239
+ - performance-tests/raw_test.rb
236
240
  - performance-tests/test_helper.rb
237
241
  - spec/functional/advices_on_private_methods_spec.rb
238
242
  - spec/functional/aspect_on_eigen_class_spec.rb
@@ -249,32 +253,40 @@ files:
249
253
  - spec/unit/before_spec.rb
250
254
  - spec/unit/deferred_logic_spec.rb
251
255
  - spec/unit/method_matcher_spec.rb
256
+ - spec/unit/raw_spec.rb
257
+ has_rdoc: true
252
258
  homepage: http://github.com/gcao/aspector
253
- licenses:
259
+ licenses:
254
260
  - MIT
255
261
  post_install_message:
256
262
  rdoc_options: []
257
- require_paths:
263
+
264
+ require_paths:
258
265
  - lib
259
- required_ruby_version: !ruby/object:Gem::Requirement
266
+ required_ruby_version: !ruby/object:Gem::Requirement
260
267
  none: false
261
- requirements:
262
- - - ! '>='
263
- - !ruby/object:Gem::Version
264
- version: '0'
265
- segments:
268
+ requirements:
269
+ - - ">="
270
+ - !ruby/object:Gem::Version
271
+ hash: 3
272
+ segments:
266
273
  - 0
267
- hash: 3014402332352836990
268
- required_rubygems_version: !ruby/object:Gem::Requirement
274
+ version: "0"
275
+ required_rubygems_version: !ruby/object:Gem::Requirement
269
276
  none: false
270
- requirements:
271
- - - ! '>='
272
- - !ruby/object:Gem::Version
273
- version: '0'
277
+ requirements:
278
+ - - ">="
279
+ - !ruby/object:Gem::Version
280
+ hash: 3
281
+ segments:
282
+ - 0
283
+ version: "0"
274
284
  requirements: []
285
+
275
286
  rubyforge_project:
276
- rubygems_version: 1.8.18
287
+ rubygems_version: 1.6.2
277
288
  signing_key:
278
289
  specification_version: 3
279
290
  summary: Aspect Oriented Ruby Programming
280
291
  test_files: []
292
+