File: interceptors2.rb

package info (click to toggle)
libneedle-ruby 1.2.0-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 1,436 kB
  • ctags: 886
  • sloc: ruby: 4,464; makefile: 52
file content (70 lines) | stat: -rw-r--r-- 2,029 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
$:.unshift "../lib"

require 'benchmark'
require 'needle'

ITERATIONS = 10_000

class UnloggedBeast
  def value( p1, p2 )
    [ p1, p2 ]
  end
end

class LoggedBeast < UnloggedBeast
  attr_writer :log

  def value( p1, p2 )
    @log.debug( "value(#{p1.inspect}, #{p2.inspect})" ) if @log.debug?
    result = super
    @log.debug( "value(...) => #{result.inspect}" ) if @log.debug?
    return result
  rescue Exception => e
    @log.debug( "value(...) raised #{e.message.inspect} (#{e.class})" ) if @log.debug?
    raise
  end
end

registry = Needle::Registry.new( :logs=> { :filename=>"/dev/null" } )
registry.register( :direct ) do
  beast = LoggedBeast.new
  beast.log = registry.logs.get( "direct" )
  beast
end

registry.register( :intercepted_doing ) { UnloggedBeast.new }
registry.register( :intercepted_with ) { UnloggedBeast.new }

registry.intercept( :intercepted_doing ).
  with_options( :log => registry.logs.get( "doing" ) ).
  doing do |chain,ctx|
    log = ctx.data[:options][:log]
    begin
      log.debug( "#{ctx.sym}(#{ctx.args.map{|i|i.inspect}.join(",")})" ) if log.debug?
      result = chain.process_next(ctx)
      log.debug( "#{ctx.sym}(...) => #{result.inspect}" ) if log.debug?
      result
    rescue Exception 
      log.debug( "value(...) raised #{e.message.inspect} (#{e.class})" ) if log.debug?
    end
  end

registry.intercept( :intercepted_with ).with { registry.logging_interceptor }

direct = registry.direct
intercepted_doing = registry.intercepted_doing
intercepted_with = registry.intercepted_with

puts
puts "--------------------------------------------------------------------"
puts "Direct method dispatch vs. intercepted method dispatch (non-trivial)"
puts "#{ITERATIONS} iterations"
puts

Benchmark.bm(20) do |x|
  x.report( "direct:" ) { ITERATIONS.times { direct.value( :a, :b ) } }
  x.report( "intercepted (doing):" ) { ITERATIONS.times { intercepted_doing.value( :a, :b ) } }
  x.report( "intercepted (with):" ) { ITERATIONS.times { intercepted_with.value( :a, :b ) } }
end

puts