power_trace 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50de15a293011f6ecb4eea0b038887a8f7464d6710a0ab1ec86d543fe672d6d5
4
- data.tar.gz: a30ed54a320eed790138bc06d0a440718aa3d684e1aaacb9d18b8fbad2cc8ac0
3
+ metadata.gz: 75a503a2bc8b1ee1123f7b37cf6a1e8ce7873256cf85b0c9cb00371fb17239d2
4
+ data.tar.gz: 41aaddfe26306041d6a580c7a212018eae7df3b3f289b0ed02dbba6ccf59d5a7
5
5
  SHA512:
6
- metadata.gz: a1180aaa9d14886e1ae1f97c71cc021a9dac81e50023030d920665852c3ff703746c4557a7f0d3b049bb5b3384c116ce39e32f99725195bad82e225a0f27f3dc
7
- data.tar.gz: 3cc3f32b84765bb5474e6dc64a17d44b1398b4b87e8c66d7716ec90a0d5d9581a8ae5ff6571e7cca870bc3dde43177eed2a0f0ddf21e2ef04150037c0c81969d
6
+ metadata.gz: b19155914a1f24eca4f1e71731ed1f2128190e9399f14b10e6a5eeaa715aa69effbb7760ec303e26d6bb2241ee7a9ec215b08f132aa1753e6813f74a9b528a0e
7
+ data.tar.gz: cfd37781a60288fd72a2cab5ff052eee371a5f0b4bae99bb5ce503aa59180a197b3911b22ce9b99c82f71a1e68e375deb2add39ec0fd83524c2d1413532162d8
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- power_trace (0.2.1)
4
+ power_trace (0.2.2)
5
5
  activesupport
6
6
  binding_of_caller (~> 0.8.0)
7
7
 
@@ -44,7 +44,7 @@ GEM
44
44
  thread_safe (0.3.6)
45
45
  tzinfo (1.2.7)
46
46
  thread_safe (~> 0.1)
47
- zeitwerk (2.3.1)
47
+ zeitwerk (2.4.0)
48
48
 
49
49
  PLATFORMS
50
50
  ruby
data/README.md CHANGED
@@ -50,12 +50,7 @@ It should look just like the normal `puts(caller)`, just colorized and with more
50
50
 
51
51
  Except for the call site, each entry also contains rich information about the runtime context. You can build your own debugging tool with that information easily.
52
52
 
53
- There are 2 types of entries:
54
-
55
- - `MethodEntry`- a method call's trace
56
- - `BlockEntry` - a block evaluation's trace
57
-
58
- They both have these attributes:
53
+ Every entry has these attributes:
59
54
 
60
55
  - `filepath`
61
56
  - `line_number`
@@ -64,9 +59,7 @@ They both have these attributes:
64
59
  - `locals` - local variables in that frame
65
60
  - `arguments`
66
61
  - the method call's arguments
67
- - will always be empty for a `BlockEntry`
68
-
69
- ![use individual entries](https://github.com/st0012/power_trace/blob/master/images/entries.png)
62
+ - will be empty for `block` entries
70
63
 
71
64
  #### Convert It Into Backtraces
72
65
 
@@ -0,0 +1,110 @@
1
+ require 'benchmark'
2
+ lib = File.expand_path("../lib", __dir__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ n = 1_000
6
+
7
+ class Foo
8
+ def first_call
9
+ second_call(20)
10
+ end
11
+
12
+ def second_call(num)
13
+ third_call_with_block do |ten|
14
+ forth_call(num, ten)
15
+ end
16
+ end
17
+
18
+ def third_call_with_block(&block)
19
+ yield(10)
20
+ end
21
+
22
+ def forth_call(num1, num2)
23
+ raise "Foo Error"
24
+ end
25
+ end
26
+
27
+ foo = Foo.new
28
+
29
+ Benchmark.benchmark do |bm|
30
+ bench_proc = proc do
31
+ 3.times do
32
+ bm.report do
33
+ n.times do
34
+ foo.first_call rescue nil
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ puts "#{n} times - ruby #{RUBY_VERSION}"
41
+ puts("Normal raise")
42
+
43
+ bench_proc.call
44
+
45
+ puts("====================================")
46
+ puts("======= power_trace required =======")
47
+ puts("====================================")
48
+
49
+ require "power_trace"
50
+
51
+ cases = [
52
+ {
53
+ replace_backtrace: false,
54
+ trace_limit: 10
55
+ },
56
+ {
57
+ replace_backtrace: false,
58
+ trace_limit: 50
59
+ },
60
+ {
61
+ replace_backtrace: true,
62
+ trace_limit: 10
63
+ },
64
+ {
65
+ replace_backtrace: true,
66
+ trace_limit: 50
67
+ }
68
+ ]
69
+
70
+ cases.each do |setup|
71
+ PowerTrace.replace_backtrace = setup[:replace_backtrace]
72
+ PowerTrace.trace_limit = setup[:trace_limit]
73
+
74
+ message =
75
+ if setup[:replace_backtrace]
76
+ "Raise and replace backtrace (trace_limit: #{PowerTrace.trace_limit})"
77
+ else
78
+ "Raise and store power_trace (trace_limit: #{PowerTrace.trace_limit})"
79
+ end
80
+
81
+ puts(message)
82
+ bench_proc.call
83
+ end
84
+ end
85
+
86
+ # 1000 times - ruby 2.7.1
87
+ # Normal raise
88
+ # 0.002032 0.000093 0.002125 ( 0.002119)
89
+ # 0.001131 0.000107 0.001238 ( 0.001239)
90
+ # 0.001092 0.000100 0.001192 ( 0.001192)
91
+ # ====================================
92
+ # ======= power_trace required =======
93
+ # ====================================
94
+ # Raise and store power_trace (trace_limit: 10)
95
+ # 0.157296 0.001807 0.159103 ( 0.159504)
96
+ # 0.159911 0.000668 0.160579 ( 0.160961)
97
+ # 0.152814 0.000493 0.153307 ( 0.153658)
98
+ # Raise and store power_trace (trace_limit: 50)
99
+ # 0.228311 0.000649 0.228960 ( 0.229264)
100
+ # 0.248271 0.001956 0.250227 ( 0.257272)
101
+ # 0.229469 0.000923 0.230392 ( 0.230822)
102
+ # Raise and replace backtrace (trace_limit: 10)
103
+ # 0.331577 0.000360 0.331937 ( 0.332203)
104
+ # 0.354934 0.001634 0.356568 ( 0.356939)
105
+ # 0.334688 0.001201 0.335889 ( 0.336682)
106
+ # Raise and replace backtrace (trace_limit: 50)
107
+ # 0.557920 0.002530 0.560450 ( 0.561101)
108
+ # 0.553058 0.001767 0.554825 ( 0.555651)
109
+ # 0.560771 0.002160 0.562931 ( 0.563613)
110
+
@@ -11,9 +11,20 @@ module PowerTrace
11
11
  cattr_accessor :power_rspec_trace, instance_accessor: false
12
12
  self.power_rspec_trace = false
13
13
 
14
+ cattr_accessor :trace_limit, instance_accessor: false
15
+ self.trace_limit = 50
16
+
14
17
  def power_trace(options = {})
15
18
  PowerTrace::Stack.new(options)
16
19
  end
20
+
21
+ class << self
22
+ def print_power_trace_error(exception)
23
+ puts(exception)
24
+ puts(exception.backtrace)
25
+ puts("there's a bug in power_trace, please open an issue at https://github.com/st0012/power_trace")
26
+ end
27
+ end
17
28
  end
18
29
 
19
30
  include PowerTrace
@@ -132,8 +132,23 @@ module PowerTrace
132
132
 
133
133
  [locals, arguments]
134
134
  end
135
+
136
+ def method
137
+ @method ||= Object.instance_method(:method).bind(@receiver).call(name)
138
+ rescue NameError
139
+ # if any part of the program uses Refinement to extend its methods
140
+ # we might still get NoMethodError when trying to get that method outside the scope
141
+ nil
142
+ end
143
+
144
+ private
145
+
146
+ def method_parameters
147
+ if method
148
+ method.parameters.map { |parameter| parameter[1] }
149
+ else
150
+ []
151
+ end
152
+ end
135
153
  end
136
154
  end
137
-
138
- require "power_trace/entries/method_entry"
139
- require "power_trace/entries/block_entry"
@@ -30,12 +30,10 @@ TracePoint.trace(:raise) do |tp|
30
30
 
31
31
  if PowerTrace.replace_backtrace
32
32
  e.set_backtrace(
33
- e.stored_power_trace.to_backtrace(colorize: PowerTrace.colorize_backtrace)
33
+ e.stored_power_trace.to_backtrace
34
34
  )
35
35
  end
36
36
  rescue => e
37
- puts(e)
38
- puts(e.backtrace)
39
- puts("power_trace's BUG")
37
+ PowerTrace.print_power_trace_error(e)
40
38
  end
41
39
  end
@@ -3,15 +3,13 @@ RSpec::Core::Formatters::ExceptionPresenter.class_eval do
3
3
 
4
4
  def formatted_backtrace(exception=@exception)
5
5
  if PowerTrace.power_rspec_trace || PowerTrace.replace_backtrace
6
- backtrace_formatter.format_backtrace(exception.stored_power_trace.to_backtrace(extra_info_indent: 8), example.metadata) +
7
- formatted_cause(exception)
6
+ backtrace = exception.stored_power_trace.to_backtrace(extra_info_indent: 8)
7
+ backtrace_formatter.format_backtrace(backtrace, example.metadata) + formatted_cause(exception)
8
8
  else
9
9
  original_formatted_backtrace
10
10
  end
11
11
  rescue => e
12
- puts(e)
13
- puts(e.backtrace)
14
- puts("there's a bug in power_trace, please open an issue at https://github.com/st0012/power_trace")
12
+ PowerTrace.print_power_trace_error(e)
15
13
  original_formatted_backtrace
16
14
  end
17
15
  end
@@ -24,6 +24,7 @@ module PowerTrace
24
24
  end
25
25
 
26
26
  def to_backtrace(output_options = {})
27
+ output_options[:colorize] = output_options.fetch(:colorize, PowerTrace.colorize_backtrace) if @exception
27
28
  output_options = extract_output_options(output_options)
28
29
  @entries.map { |e| e.to_s(output_options) }
29
30
  end
@@ -52,16 +53,14 @@ module PowerTrace
52
53
  power_trace_index = (frames.index { |b| b.frame_description&.to_sym == :power_trace } || 0) + 1
53
54
  power_trace_index += 1 if @exception
54
55
 
55
- frames[power_trace_index..].map do |b|
56
- case b.frame_type
57
- when :method
58
- MethodEntry.new(b)
59
- when :block
60
- BlockEntry.new(b)
56
+ end_index =
57
+ if @exception
58
+ power_trace_index + PowerTrace.trace_limit - 1
61
59
  else
62
- Entry.new(b)
60
+ -1
63
61
  end
64
- end
62
+
63
+ frames[power_trace_index..end_index].map { |b| Entry.new(b) }
65
64
  end
66
65
  end
67
66
  end
@@ -1,3 +1,3 @@
1
1
  module PowerTrace
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: power_trace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - st0012
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-13 00:00:00.000000000 Z
11
+ date: 2020-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -75,6 +75,7 @@ files:
75
75
  - LICENSE.txt
76
76
  - README.md
77
77
  - Rakefile
78
+ - benchmarks/raise_with_power_trace.rb
78
79
  - bin/console
79
80
  - bin/setup
80
81
  - images/entries.png
@@ -84,8 +85,6 @@ files:
84
85
  - images/power_trace_rspec_error.png
85
86
  - images/print_directly.png
86
87
  - lib/power_trace.rb
87
- - lib/power_trace/entries/block_entry.rb
88
- - lib/power_trace/entries/method_entry.rb
89
88
  - lib/power_trace/entry.rb
90
89
  - lib/power_trace/exception_patch.rb
91
90
  - lib/power_trace/helpers/colorize_helper.rb
@@ -1,4 +0,0 @@
1
- module PowerTrace
2
- class BlockEntry < Entry
3
- end
4
- end
@@ -1,25 +0,0 @@
1
- module PowerTrace
2
- class MethodEntry < Entry
3
- def method
4
- @method ||= Object.instance_method(:method).bind(@receiver).call(name)
5
- rescue NameError
6
- # if any part of the program uses Refinement to extend its methods
7
- # we might still get NoMethodError when trying to get that method outside the scope
8
- nil
9
- end
10
-
11
- private
12
-
13
- def method_parameters
14
- if method
15
- method.parameters.map { |parameter| parameter[1] }
16
- else
17
- []
18
- end
19
- end
20
-
21
- def defined_class
22
- method.owner
23
- end
24
- end
25
- end