dexc 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ .bundle
2
+ Gemfile.lock
3
+ pkg/*
4
+ vendor/*
data/BSDL ADDED
@@ -0,0 +1,23 @@
1
+ Copyright (C) 2013 Kazuki Tsujimoto, All rights reserved.
2
+ Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. (lib/irb.rb)
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions
6
+ are met:
7
+ 1. Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+
13
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
+ SUCH DAMAGE.
data/COPYING ADDED
@@ -0,0 +1,58 @@
1
+ Copyright (C) 2013 Kazuki Tsujimoto, All rights reserved.
2
+ Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. (lib/irb.rb)
3
+
4
+ You can redistribute it and/or modify it under either the terms of the
5
+ 2-clause BSDL (see the file BSDL), or the conditions below:
6
+
7
+ 1. You may make and give away verbatim copies of the source form of the
8
+ software without restriction, provided that you duplicate all of the
9
+ original copyright notices and associated disclaimers.
10
+
11
+ 2. You may modify your copy of the software in any way, provided that
12
+ you do at least ONE of the following:
13
+
14
+ a) place your modifications in the Public Domain or otherwise
15
+ make them Freely Available, such as by posting said
16
+ modifications to Usenet or an equivalent medium, or by allowing
17
+ the author to include your modifications in the software.
18
+
19
+ b) use the modified software only within your corporation or
20
+ organization.
21
+
22
+ c) give non-standard binaries non-standard names, with
23
+ instructions on where to get the original software distribution.
24
+
25
+ d) make other distribution arrangements with the author.
26
+
27
+ 3. You may distribute the software in object code or binary form,
28
+ provided that you do at least ONE of the following:
29
+
30
+ a) distribute the binaries and library files of the software,
31
+ together with instructions (in the manual page or equivalent)
32
+ on where to get the original distribution.
33
+
34
+ b) accompany the distribution with the machine-readable source of
35
+ the software.
36
+
37
+ c) give non-standard binaries non-standard names, with
38
+ instructions on where to get the original software distribution.
39
+
40
+ d) make other distribution arrangements with the author.
41
+
42
+ 4. You may modify and include the part of the software into any other
43
+ software (possibly commercial). But some files in the distribution
44
+ are not written by the author, so that they are not under these terms.
45
+
46
+ For the list of those files and their copying conditions, see the
47
+ file LEGAL.
48
+
49
+ 5. The scripts and library files supplied as input to or produced as
50
+ output from the software do not automatically fall under the
51
+ copyright of the software, but belong to whomever generated them,
52
+ and may be sold commercially, and may be aggregated with this
53
+ software.
54
+
55
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
56
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
57
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
58
+ PURPOSE.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.rdoc ADDED
@@ -0,0 +1,60 @@
1
+ = dexc
2
+ == About
3
+ Automatically start the REPL and show trace on an exception to debug.
4
+
5
+ == Requirements
6
+ * Ruby 2.0.0 or later
7
+ * Pry(optional)
8
+
9
+ == Installation
10
+ $ gem install dexc
11
+
12
+ == Examples
13
+ $ cat t.rb
14
+ def m(obj)
15
+ obj.to_s + 1
16
+ end
17
+
18
+ m(0)
19
+
20
+ $ ruby -rdexc t.rb
21
+ 0:lib/dexc.rb:82> tp.enable
22
+ TracePoint#enable: false
23
+ 1:lib/dexc.rb:83> end
24
+ Dexc#start: false
25
+ 2:lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45> return gem_original_require(path)
26
+ Kernel#gem_original_require: true
27
+ 3:lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:45> return gem_original_require(path)
28
+ Kernel#require: true
29
+ 4:t.rb:0>
30
+ IO#set_encoding: #<File:t.rb (closed)>
31
+ 5:t.rb:0>
32
+ IO#set_encoding: #<File:t.rb (closed)>
33
+ 6:t.rb:1> def m(obj)
34
+ Module#method_added: nil
35
+ 7:t.rb:2> obj.to_s + 1
36
+ Fixnum#to_s: "0"
37
+ 8:t.rb:2> obj.to_s + 1
38
+ Exception#initialize: #<TypeError: no implicit conversion of Fixnum into String>
39
+ 9:t.rb:2> obj.to_s + 1
40
+ Class#new: #<TypeError: no implicit conversion of Fixnum into String>
41
+ 10:t.rb:2> obj.to_s + 1
42
+ Exception#exception: #<TypeError: no implicit conversion of Fixnum into String>
43
+ 11:t.rb:2> obj.to_s + 1
44
+ Exception#backtrace: nil
45
+
46
+ TypeError: no implicit conversion of Fixnum into String
47
+ from t.rb:2:in `+'
48
+ from t.rb:2:in `m'
49
+ from t.rb:4:in `<main>'
50
+
51
+ From: t.rb @ line 2 Object#m:
52
+
53
+ 1: def m(obj)
54
+ => 2: obj.to_s + 1
55
+ 3: end
56
+
57
+ [1] pry(main)> obj
58
+ => 0
59
+ [2] pry(main)> hist[7] # or dexc_hist[7]
60
+ => "0"
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ ENV['BUNDLE_GEMFILE'] = File.expand_path('../Gemfile', __FILE__)
2
+ require 'bundler/setup'
3
+ require "bundler/gem_tasks"
4
+
5
+ require "rake/testtask"
6
+ task :default => :test
7
+ Rake::TestTask.new do |t|
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/test_*.rb"]
10
+ end
data/dexc.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+ require 'dexc/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'dexc'
6
+ s.version = Dexc::VERSION
7
+ s.authors = ['Kazuki Tsujimoto']
8
+ s.email = ['kazuki@callcc.net']
9
+ s.homepage = 'https://github.com/k-tsj/dexc'
10
+ s.summary = %q{A library that helps you to debug an exception}
11
+ s.description = %q{Automatically start the REPL and show trace on an exception to debug.}
12
+
13
+ s.files = `git ls-files`.split("\n")
14
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f) }
16
+ s.require_paths = ['lib']
17
+ s.add_development_dependency 'rake'
18
+ s.extra_rdoc_files = ['README.rdoc']
19
+ s.rdoc_options = ['--main', 'README.rdoc']
20
+ end
data/lib/dexc.rb ADDED
@@ -0,0 +1,138 @@
1
+ # dexc.rb
2
+ #
3
+ # Copyright (C) 2013 Kazuki Tsujimoto, All rights reserved.
4
+
5
+ require 'dexc/version'
6
+
7
+ module Dexc
8
+ EXC_BINDING_VAR = :@dexc_binding
9
+
10
+ class RingBuffer
11
+ def initialize(n)
12
+ @n = n
13
+ @buf = []
14
+ @idx = 0
15
+ end
16
+
17
+ def add(val)
18
+ @buf[@idx] = val
19
+ @idx = (@idx + 1) % @n
20
+ end
21
+
22
+ def to_a
23
+ @buf[@idx..-1] + @buf[0...@idx]
24
+ end
25
+ end
26
+
27
+ RaiseEvent = Struct.new(:event, :raised_exception)
28
+ ReturnEvent = Struct.new(:event, :lineno, :path, :defined_class, :method_id, :return_value)
29
+
30
+ def start
31
+ events = RingBuffer.new(30)
32
+
33
+ tp = TracePoint.new(:raise, :return, :c_return, :b_return) do |tp|
34
+ if tp.event == :raise
35
+ exc = tp.raised_exception
36
+ exc.instance_variable_set(EXC_BINDING_VAR, tp.binding)
37
+ events.add(RaiseEvent.new(tp.event, exc))
38
+ else
39
+ events.add(ReturnEvent.new(tp.event, tp.lineno, tp.path, tp.defined_class, tp.method_id, tp.return_value))
40
+ end
41
+ end
42
+
43
+ at_exit do
44
+ exc = $!
45
+ tp.disable
46
+ b = exc.instance_variable_get(EXC_BINDING_VAR)
47
+ if exc.kind_of?(StandardError) and b
48
+ raise_idx = events.to_a.find_index {|i| i.event == :raise and i.raised_exception == exc }
49
+ latest_events = raise_idx ? events.to_a[0...raise_idx] : []
50
+ return_events = latest_events.find_all {|i| i.event != :raise }
51
+ return_values = return_events.map(&:return_value)
52
+
53
+ show_trace(return_events)
54
+ error_print(exc)
55
+
56
+ Kernel.module_eval do
57
+ define_method(:dexc_hist) do
58
+ return_values
59
+ end
60
+ alias_method :hist, :dexc_hist
61
+ end
62
+
63
+ begin
64
+ require 'pry'
65
+ b.pry
66
+ rescue LoadError
67
+ require 'irb'
68
+ IRB::Irb.module_eval do
69
+ alias_method :eval_input_orig, :eval_input
70
+ define_method(:eval_input) do
71
+ IRB::Irb.module_eval { alias_method :eval_input, :eval_input_orig }
72
+ require 'irb/ext/multi-irb'
73
+ IRB.irb(nil, b)
74
+ end
75
+ end
76
+ IRB.start
77
+ end
78
+ exit!
79
+ end
80
+ end
81
+
82
+ tp.enable
83
+ end
84
+ module_function :start
85
+
86
+ def show_trace(events)
87
+ idx_width = (events.length - 1).to_s.length
88
+ file_cache = {}
89
+ events.each_with_index do |i, idx|
90
+ show_line(i.path, i.lineno, idx, idx_width, file_cache)
91
+ puts " " * (idx_width + 1) + "#{i.defined_class}##{i.method_id}#{i.event == :b_return ? '(block)' : ''}: #{i.return_value.inspect}"
92
+ end
93
+ puts
94
+ end
95
+ module_function :show_trace
96
+
97
+ def show_line(path, lineno, index, index_width, cache)
98
+ print "#{"%#{index_width}d" % index}:#{path}:#{lineno}"
99
+ begin
100
+ cache[path] ||= open(path).each_line.map(&:chomp)
101
+ print "> #{lineno > 0 ? cache[path][lineno - 1] : ''}"
102
+ rescue Errno::ENOENT
103
+ cache[path] = []
104
+ end
105
+ puts
106
+ end
107
+ module_function :show_line
108
+
109
+ # from Irb#eval_input(lib/irb.rb)
110
+ def error_print(exc)
111
+ print exc.class, ": ", exc, "\n"
112
+ messages = []
113
+ lasts = []
114
+ levels = 0
115
+ back_trace_limit = 30
116
+ for m in exc.backtrace
117
+ if m
118
+ if messages.size < back_trace_limit
119
+ messages.push "\tfrom "+m
120
+ else
121
+ lasts.push "\tfrom "+m
122
+ if lasts.size > back_trace_limit
123
+ lasts.shift
124
+ levels += 1
125
+ end
126
+ end
127
+ end
128
+ end
129
+ print messages.join("\n"), "\n"
130
+ unless lasts.empty?
131
+ printf "... %d levels...\n", levels if levels > 0
132
+ print lasts.join("\n")
133
+ end
134
+ end
135
+ module_function :error_print
136
+ end
137
+
138
+ Dexc.start
@@ -0,0 +1,3 @@
1
+ module Dexc
2
+ VERSION = "0.0.1"
3
+ end
data/test/test_dexc.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'test/unit'
2
+
3
+ class TestDexc < Test::Unit::TestCase
4
+ def test_load
5
+ assert_nothing_raised do
6
+ require_relative '../lib/dexc'
7
+ end
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dexc
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kazuki Tsujimoto
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Automatically start the REPL and show trace on an exception to debug.
31
+ email:
32
+ - kazuki@callcc.net
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files:
36
+ - README.rdoc
37
+ files:
38
+ - .gitignore
39
+ - BSDL
40
+ - COPYING
41
+ - Gemfile
42
+ - README.rdoc
43
+ - Rakefile
44
+ - dexc.gemspec
45
+ - lib/dexc.rb
46
+ - lib/dexc/version.rb
47
+ - test/test_dexc.rb
48
+ homepage: https://github.com/k-tsj/dexc
49
+ licenses: []
50
+ post_install_message:
51
+ rdoc_options:
52
+ - --main
53
+ - README.rdoc
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ segments:
63
+ - 0
64
+ hash: 2613877154168346120
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ segments:
72
+ - 0
73
+ hash: 2613877154168346120
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 1.8.23
77
+ signing_key:
78
+ specification_version: 3
79
+ summary: A library that helps you to debug an exception
80
+ test_files: []