SuperCaller 1.0.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.
- data/History.txt +5 -0
- data/Manifest.txt +6 -0
- data/README.txt +55 -0
- data/Rakefile +20 -0
- data/lib/super_caller.rb +113 -0
- data/lib/super_caller/exception.rb +31 -0
- metadata +86 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
= SuperCaller
|
2
|
+
|
3
|
+
A Kernel#caller enhancement
|
4
|
+
|
5
|
+
Documentation:
|
6
|
+
|
7
|
+
http://seattlerb.org/SuperCaller
|
8
|
+
|
9
|
+
File Bugs:
|
10
|
+
|
11
|
+
http://rubyforge.org/tracker/?func=add&group_id=1513&atid=5921
|
12
|
+
|
13
|
+
== DESCRIPTION:
|
14
|
+
|
15
|
+
SuperCaller adds a beefed-up version of Kernel#caller and a beefed up
|
16
|
+
version of Exception#backtrace.
|
17
|
+
|
18
|
+
== FEATURES/PROBLEMS:
|
19
|
+
|
20
|
+
* Can cause Ruby to crash when an Exception with SuperCaller's
|
21
|
+
backtrace reaches the top level.
|
22
|
+
|
23
|
+
== SYNOPSIS:
|
24
|
+
|
25
|
+
Regular old Kernel#super_caller:
|
26
|
+
|
27
|
+
require 'super_caller'
|
28
|
+
|
29
|
+
def something() super_caller end
|
30
|
+
stack = something
|
31
|
+
p stack.first.file # => "-"
|
32
|
+
p stack.first.line # => 4
|
33
|
+
p stack.first.method_name # => nil
|
34
|
+
p stack.first.self # => main
|
35
|
+
p stack.first.sexp # => [:vcall, :super_caller]
|
36
|
+
p stack.first.source # => "def something\n super_caller\nend"
|
37
|
+
|
38
|
+
Fancy Exception#backtrace:
|
39
|
+
|
40
|
+
require 'super_caller/exception'
|
41
|
+
|
42
|
+
def raiser() raise end
|
43
|
+
|
44
|
+
def raisee
|
45
|
+
raiser
|
46
|
+
rescue => e
|
47
|
+
p e.backtrace.first.sexp
|
48
|
+
end
|
49
|
+
|
50
|
+
raiser # => [:vcall, :raise]
|
51
|
+
|
52
|
+
== INSTALL:
|
53
|
+
|
54
|
+
sudo gem install SuperCaller
|
55
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
require './lib/super_caller.rb'
|
6
|
+
|
7
|
+
Hoe.new('SuperCaller', SuperCaller::VERSION) do |p|
|
8
|
+
p.rubyforge_name = 'seattlerb'
|
9
|
+
p.author = 'Eric Hodel'
|
10
|
+
p.email = 'drbrain@segment7.net'
|
11
|
+
p.summary = p.paragraphs_of('README.txt', 1).first
|
12
|
+
p.description = p.paragraphs_of('README.txt', 7).first
|
13
|
+
p.url = p.paragraphs_of('README.txt', 3).first
|
14
|
+
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
15
|
+
|
16
|
+
p.extra_deps << ['ParseTree', '~> 2.0']
|
17
|
+
p.extra_deps << ['ruby2ruby', '~> 1.1']
|
18
|
+
end
|
19
|
+
|
20
|
+
# vim: syntax=Ruby
|
data/lib/super_caller.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'inline'
|
3
|
+
require 'parse_tree'
|
4
|
+
require 'ruby2ruby'
|
5
|
+
|
6
|
+
module SuperCaller
|
7
|
+
|
8
|
+
VERSION = '1.0.0'
|
9
|
+
|
10
|
+
Frame = Struct.new :file, :line, :method_name, :self, :sexp
|
11
|
+
|
12
|
+
class Frame
|
13
|
+
def to_s
|
14
|
+
if method_name then
|
15
|
+
"%s:%d:in `%s'" % [file, line, method_name]
|
16
|
+
else
|
17
|
+
"%s:%d" % [file, line]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
alias to_str to_s
|
22
|
+
|
23
|
+
def split(*args)
|
24
|
+
to_s.split(*args)
|
25
|
+
end
|
26
|
+
|
27
|
+
def source
|
28
|
+
return unless method_name
|
29
|
+
sexp = Sexp.for self.self.class, method_name, true
|
30
|
+
return if s(nil) == sexp
|
31
|
+
RubyToRuby.new.process sexp rescue nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
inline :C do |builder|
|
36
|
+
builder.include '"ruby.h"'
|
37
|
+
builder.include '"node.h"'
|
38
|
+
builder.include '"env.h"'
|
39
|
+
|
40
|
+
builder.prefix <<-'EOF'
|
41
|
+
static VALUE rb_mSuperCaller = Qnil;
|
42
|
+
static VALUE rb_cSuperCaller_Frame = Qnil;
|
43
|
+
|
44
|
+
void add_to_parse_tree(VALUE ary,
|
45
|
+
NODE * n,
|
46
|
+
VALUE newlines,
|
47
|
+
ID * locals);
|
48
|
+
|
49
|
+
static VALUE node_to_sexp(NODE * node) {
|
50
|
+
VALUE sexp = rb_ary_new();
|
51
|
+
|
52
|
+
add_to_parse_tree(sexp, node, Qfalse, NULL);
|
53
|
+
|
54
|
+
if (RARRAY(sexp)->len == 0) {
|
55
|
+
return Qnil;
|
56
|
+
} else {
|
57
|
+
return RARRAY(sexp)->ptr[0];
|
58
|
+
}
|
59
|
+
}
|
60
|
+
EOF
|
61
|
+
|
62
|
+
builder.c <<-'EOF'
|
63
|
+
static VALUE
|
64
|
+
super_caller() {
|
65
|
+
struct FRAME * c_frame = ruby_frame;
|
66
|
+
VALUE r_frame, stack, method_name;
|
67
|
+
NODE * n;
|
68
|
+
|
69
|
+
if (NIL_P(rb_cSuperCaller_Frame)) {
|
70
|
+
rb_mSuperCaller =
|
71
|
+
rb_const_get(rb_cObject, rb_intern("SuperCaller"));
|
72
|
+
rb_cSuperCaller_Frame =
|
73
|
+
rb_const_get(rb_mSuperCaller, rb_intern("Frame"));
|
74
|
+
}
|
75
|
+
|
76
|
+
stack = rb_ary_new();
|
77
|
+
|
78
|
+
if (c_frame->last_func == ID_ALLOCATOR)
|
79
|
+
c_frame = c_frame->prev;
|
80
|
+
|
81
|
+
for (; c_frame && (n = c_frame->node); c_frame = c_frame->prev) {
|
82
|
+
if (c_frame->prev && c_frame->prev->last_func) {
|
83
|
+
if (c_frame->prev->node == n) {
|
84
|
+
if (c_frame->prev->last_func == c_frame->last_func)
|
85
|
+
continue;
|
86
|
+
}
|
87
|
+
|
88
|
+
method_name = ID2SYM(c_frame->prev->last_func);
|
89
|
+
} else {
|
90
|
+
method_name = Qnil;
|
91
|
+
}
|
92
|
+
|
93
|
+
r_frame = rb_funcall(rb_cSuperCaller_Frame, rb_intern("new"), 5,
|
94
|
+
rb_str_new2(n->nd_file),
|
95
|
+
INT2FIX(nd_line(n)),
|
96
|
+
method_name,
|
97
|
+
c_frame->self,
|
98
|
+
node_to_sexp(n));
|
99
|
+
|
100
|
+
rb_ary_push(stack, r_frame);
|
101
|
+
}
|
102
|
+
|
103
|
+
return stack;
|
104
|
+
}
|
105
|
+
EOF
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
class Object
|
111
|
+
include SuperCaller
|
112
|
+
end
|
113
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'super_caller'
|
2
|
+
|
3
|
+
module Kernel
|
4
|
+
|
5
|
+
alias old_raise raise
|
6
|
+
|
7
|
+
def raise(*args)
|
8
|
+
old_raise(*args)
|
9
|
+
rescue Exception => e
|
10
|
+
e.backtrace = super_caller[1..-1]
|
11
|
+
old_raise e
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
class Exception
|
17
|
+
|
18
|
+
alias old_backtrace backtrace
|
19
|
+
|
20
|
+
attr_reader :backtrace
|
21
|
+
|
22
|
+
alias old_set_backtrace set_backtrace
|
23
|
+
|
24
|
+
def backtrace=(backtrace)
|
25
|
+
old_set_backtrace backtrace.map { |frame| frame.to_s }
|
26
|
+
@backtrace = backtrace
|
27
|
+
end
|
28
|
+
|
29
|
+
alias set_backtrace backtrace=
|
30
|
+
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.4.3
|
3
|
+
specification_version: 1
|
4
|
+
name: SuperCaller
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.0.0
|
7
|
+
date: 2007-08-04 00:00:00 -07:00
|
8
|
+
summary: A Kernel#caller enhancement
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: drbrain@segment7.net
|
12
|
+
homepage: http://seattlerb.org/SuperCaller
|
13
|
+
rubyforge_project: seattlerb
|
14
|
+
description: SuperCaller adds a beefed-up version of Kernel#caller and a beefed up version of Exception#backtrace.
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.0.0
|
30
|
+
version:
|
31
|
+
platform: ruby
|
32
|
+
signing_key:
|
33
|
+
cert_chain:
|
34
|
+
post_install_message:
|
35
|
+
authors:
|
36
|
+
- Eric Hodel
|
37
|
+
files:
|
38
|
+
- History.txt
|
39
|
+
- Manifest.txt
|
40
|
+
- README.txt
|
41
|
+
- Rakefile
|
42
|
+
- lib/super_caller.rb
|
43
|
+
- lib/super_caller/exception.rb
|
44
|
+
test_files: []
|
45
|
+
|
46
|
+
rdoc_options:
|
47
|
+
- --main
|
48
|
+
- README.txt
|
49
|
+
extra_rdoc_files:
|
50
|
+
- History.txt
|
51
|
+
- Manifest.txt
|
52
|
+
- README.txt
|
53
|
+
executables: []
|
54
|
+
|
55
|
+
extensions: []
|
56
|
+
|
57
|
+
requirements: []
|
58
|
+
|
59
|
+
dependencies:
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: ParseTree
|
62
|
+
version_requirement:
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ~>
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "2.0"
|
68
|
+
version:
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: ruby2ruby
|
71
|
+
version_requirement:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: "1.1"
|
77
|
+
version:
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: hoe
|
80
|
+
version_requirement:
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 1.2.2
|
86
|
+
version:
|