rextra 2.0.1 → 2.0.3
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/lib/rextra/bleeding.rb +199 -210
- data/lib/rextra/cutting.rb +3 -4
- data/lib/rextra/enddata.rb +0 -80
- data/test/tc_object.rb +2 -2
- metadata +3 -4
- data/lib/rextra/binding_of_caller.rb +0 -85
data/lib/rextra/bleeding.rb
CHANGED
@@ -12,222 +12,211 @@
|
|
12
12
|
# == Licence
|
13
13
|
# TBD
|
14
14
|
|
15
|
-
|
16
15
|
#--
|
17
|
-
# TODO doc this
|
18
16
|
# TODO review this
|
19
|
-
# TODO move to seperate project
|
20
17
|
# TODO test test test
|
21
18
|
#++
|
22
19
|
|
23
20
|
require 'rextra/cutting'
|
24
21
|
|
25
|
-
def
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
module Kernel
|
30
|
-
def call_stack
|
31
|
-
require 'ostruct'
|
32
|
-
caller.map do |c|
|
33
|
-
# TODO rewrite this regexp
|
34
|
-
m = /^([\.a-zA-Z_0-9()\/]*):(\d*)(?::in `(\S*)')?$/.match c
|
35
|
-
OpenStruct.new(:file=>m[1],:line=>m[2],:call=>m[3]) rescue nil
|
36
|
-
end.compact
|
37
|
-
end
|
38
|
-
def caller_name deep = 1
|
39
|
-
/:in `(\S*)'$/.match( caller[deep] )[1]
|
40
|
-
end
|
41
|
-
def method_name() caller_name end
|
42
|
-
end
|
43
|
-
|
44
|
-
class Object
|
45
|
-
def this
|
46
|
-
require 'weakref'
|
47
|
-
WeakRef.new self
|
48
|
-
end
|
49
|
-
def destructor str
|
50
|
-
ObjectSpace.define_finalizer this, ObjectSpace.make_proc( str )
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
class Module
|
55
|
-
#def once_methods *meths
|
56
|
-
# act_on_methods *meths do |meth|
|
57
|
-
# alias_method "__rapid_#{meth}", meth if method_defined? meth
|
58
|
-
# meta_eval { (@once ||= Set.new) << meth }
|
59
|
-
# class_eval<<-HERE
|
60
|
-
# def #{meth} *args, &block
|
61
|
-
# __rapid_#{method} *args, &block
|
62
|
-
# ensure # is this right?
|
63
|
-
# undef_methods __rapid_#{meth}
|
64
|
-
# empty_methods #{meth}
|
65
|
-
# end
|
66
|
-
# HERE
|
67
|
-
# end
|
68
|
-
#end
|
69
|
-
def module () self end
|
70
|
-
def modules() [self] + modules_up end
|
71
|
-
def module_up() eval name.sub( /(::)?\w+$/, '' ) end
|
72
|
-
def modules_up result = []
|
73
|
-
(r = module_up) ? r.modules_up( result << r ) : result end
|
74
|
-
def def_advice meth, &block
|
75
|
-
prev = self.instance_method meth.
|
76
|
-
define_method( meth ) do |*args|
|
77
|
-
block.call( prev.bind(self), *args ) end end
|
78
|
-
|
79
|
-
# TODO fix #const to look in global module
|
80
|
-
class Const
|
81
|
-
def initialize mod
|
82
|
-
@mod = mod
|
83
|
-
end
|
84
|
-
def method_missing( sym, *args )
|
85
|
-
@mod.modules.each do |mod|
|
86
|
-
return mod.const_get( sym ) if mod.const_defined? sym.to_s
|
87
|
-
end
|
88
|
-
#raise NameError, "uninitialized constant #{sym}"
|
89
|
-
nil
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
def const
|
94
|
-
Const.new self.module
|
95
|
-
end
|
96
|
-
|
97
|
-
def consts *syms
|
98
|
-
start, inc = 0, 1
|
99
|
-
start = syms.shift if syms.first.kind_of? Integer
|
100
|
-
inc = syms.pop if syms.last.kind_of? Integer
|
101
|
-
syms.each do |sym|
|
102
|
-
class_eval "#{sym.to_s.upcase} = #{start}"
|
103
|
-
start += inc
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
end
|
108
|
-
|
109
|
-
def parallel_each( *args )
|
110
|
-
args.shift.zip( *args ).each do |e|
|
111
|
-
yield( *e )
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
module Rapid
|
116
|
-
|
117
|
-
class ThreadPool
|
118
|
-
def initialize size = 10
|
119
|
-
@count, @max = 0, size
|
120
|
-
@mutex, @cond = Mutex.new, ConditionVariable.new
|
121
|
-
end
|
122
|
-
def thread *args, &block
|
123
|
-
@mutex.synchronize do
|
124
|
-
@cond.wait @mutex unless @count < @max
|
125
|
-
@count += 1
|
126
|
-
result = Thread.new(args,Thread.current,block) do |args,th,block|
|
127
|
-
begin
|
128
|
-
block.call *args
|
129
|
-
rescue => e
|
130
|
-
th.raise e
|
131
|
-
ensure
|
132
|
-
release
|
133
|
-
end end end
|
134
|
-
end
|
135
|
-
def max=(size) @mutex.synchronize { @max = size } end
|
136
|
-
private
|
137
|
-
def release
|
138
|
-
@mutex.synchronize do
|
139
|
-
@count -= 1
|
140
|
-
@cond.signal
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
VERSION = '0.0.2'
|
146
|
-
|
147
|
-
def self.tempfile name = nil
|
148
|
-
require 'tempfile'
|
149
|
-
tf = Tempfile.new name
|
150
|
-
yield tf
|
151
|
-
ensure
|
152
|
-
tf.close true
|
153
|
-
end
|
154
|
-
|
155
|
-
def self.start_daemon *args, &block
|
156
|
-
:$VERBOSE.temporary nil do
|
157
|
-
#EndData.close if $leftovers
|
158
|
-
Process.fork do
|
159
|
-
fork and exit
|
160
|
-
trap( 'INT' ) { Thread.current.kill }
|
161
|
-
$stderr = $stdout = $stdin = NullDevice.new
|
162
|
-
Process.setsid
|
163
|
-
block.call( *args )
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
def self.term_size
|
169
|
-
require 'curses'
|
170
|
-
Curses.init_screen
|
171
|
-
x, y = Curses.cols, Curses.lines
|
172
|
-
Curses.close_screen
|
173
|
-
[x, y]
|
174
|
-
ensure
|
175
|
-
Curses.close_screen
|
176
|
-
end
|
177
|
-
|
178
|
-
def self.filename
|
179
|
-
File.basename $0
|
180
|
-
end
|
181
|
-
|
182
|
-
def self.create_key size = 16 # copied from cgi/session.rb
|
183
|
-
require 'digest/md5'
|
184
|
-
md5 = Digest::MD5::new
|
185
|
-
md5.update(String(Time::now))
|
186
|
-
md5.update(String(rand(0)))
|
187
|
-
md5.update(String($$))
|
188
|
-
md5.hexdigest[0,size]
|
189
|
-
end
|
190
|
-
|
191
|
-
module Kernel
|
192
|
-
|
193
|
-
def modules() self.class.modules end
|
194
|
-
def module() self.class.module end
|
195
|
-
def module_up() self.class.module_up end
|
196
|
-
def modules_up() self.class.modules_up end
|
197
|
-
|
198
|
-
end
|
199
|
-
|
200
|
-
def required
|
201
|
-
result = []
|
202
|
-
$".each do |file|
|
203
|
-
$:.each do |path|
|
204
|
-
if File.exists?( path + '/' + file )
|
205
|
-
result << (path + '/' + file)
|
206
|
-
next
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
result
|
211
|
-
end
|
212
|
-
|
213
|
-
def required? file
|
214
|
-
(el = required.grep( /#{file}(\.rb|\.so)?$/ ).to_el).empty? ? false : el
|
22
|
+
def __TBD
|
23
|
+
raise 'TBD'
|
215
24
|
end
|
216
25
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
def
|
231
|
-
|
232
|
-
end
|
233
|
-
end
|
26
|
+
#def ObjectSpace.make_proc str
|
27
|
+
# eval "proc {#{str}}"
|
28
|
+
#end
|
29
|
+
#
|
30
|
+
#module Kernel
|
31
|
+
# def call_stack
|
32
|
+
# require 'ostruct'
|
33
|
+
# caller.map do |c|
|
34
|
+
# # TODO rewrite this regexp
|
35
|
+
# m = /^([\.a-zA-Z_0-9()\/]*):(\d*)(?::in `(\S*)')?$/.match c
|
36
|
+
# OpenStruct.new(:file=>m[1],:line=>m[2],:call=>m[3]) rescue nil
|
37
|
+
# end.compact
|
38
|
+
# end
|
39
|
+
# def caller_name deep = 1
|
40
|
+
# /:in `(\S*)'$/.match( caller[deep] )[1]
|
41
|
+
# end
|
42
|
+
# def method_name() caller_name end
|
43
|
+
#end
|
44
|
+
#
|
45
|
+
#class Object
|
46
|
+
# def this
|
47
|
+
# require 'weakref'
|
48
|
+
# WeakRef.new self
|
49
|
+
# end
|
50
|
+
# def destructor str
|
51
|
+
# ObjectSpace.define_finalizer this, ObjectSpace.make_proc( str )
|
52
|
+
# end
|
53
|
+
#end
|
54
|
+
#
|
55
|
+
#class Module
|
56
|
+
# def module () self end
|
57
|
+
# def modules() [self] + modules_up end
|
58
|
+
# def module_up() eval name.sub( /(::)?\w+$/, '' ) end
|
59
|
+
# def modules_up result = []
|
60
|
+
# (r = module_up) ? r.modules_up( result << r ) : result end
|
61
|
+
# def def_advice meth, &block
|
62
|
+
# prev = self.instance_method meth.
|
63
|
+
# define_method( meth ) do |*args|
|
64
|
+
# block.call( prev.bind(self), *args )
|
65
|
+
# end
|
66
|
+
# end
|
67
|
+
#
|
68
|
+
# # TODO fix #const to look in global module
|
69
|
+
# class Const
|
70
|
+
# def initialize mod
|
71
|
+
# @mod = mod
|
72
|
+
# end
|
73
|
+
# def method_missing( sym, *args )
|
74
|
+
# @mod.modules.each do |mod|
|
75
|
+
# return mod.const_get( sym ) if mod.const_defined? sym.to_s
|
76
|
+
# end
|
77
|
+
# #raise NameError, "uninitialized constant #{sym}"
|
78
|
+
# nil
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# def const
|
83
|
+
# Const.new self.module
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
# def consts *syms
|
87
|
+
# start, inc = 0, 1
|
88
|
+
# start = syms.shift if syms.first.kind_of? Integer
|
89
|
+
# inc = syms.pop if syms.last.kind_of? Integer
|
90
|
+
# syms.each do |sym|
|
91
|
+
# class_eval "#{sym.to_s.upcase} = #{start}"
|
92
|
+
# start += inc
|
93
|
+
# end
|
94
|
+
# end
|
95
|
+
#
|
96
|
+
#end
|
97
|
+
#
|
98
|
+
#def parallel_each( *args )
|
99
|
+
# args.shift.zip( *args ).each do |e|
|
100
|
+
# yield( *e )
|
101
|
+
# end
|
102
|
+
#end
|
103
|
+
#
|
104
|
+
#module Rapid
|
105
|
+
#
|
106
|
+
# class ThreadPool
|
107
|
+
# def initialize size = 10
|
108
|
+
# @count, @max = 0, size
|
109
|
+
# @mutex, @cond = Mutex.new, ConditionVariable.new
|
110
|
+
# end
|
111
|
+
# def thread *args, &block
|
112
|
+
# @mutex.synchronize do
|
113
|
+
# @cond.wait @mutex unless @count < @max
|
114
|
+
# @count += 1
|
115
|
+
# result = Thread.new(args,Thread.current,block) do |args,th,block|
|
116
|
+
# begin
|
117
|
+
# block.call *args
|
118
|
+
# rescue => e
|
119
|
+
# th.raise e
|
120
|
+
# ensure
|
121
|
+
# release
|
122
|
+
# end end end
|
123
|
+
# end
|
124
|
+
# def max=(size) @mutex.synchronize { @max = size } end
|
125
|
+
# private
|
126
|
+
# def release
|
127
|
+
# @mutex.synchronize do
|
128
|
+
# @count -= 1
|
129
|
+
# @cond.signal
|
130
|
+
# end
|
131
|
+
# end
|
132
|
+
# end
|
133
|
+
#
|
134
|
+
# VERSION = '0.0.2'
|
135
|
+
#
|
136
|
+
# def self.tempfile name = nil
|
137
|
+
# require 'tempfile'
|
138
|
+
# tf = Tempfile.new name
|
139
|
+
# yield tf
|
140
|
+
# ensure
|
141
|
+
# tf.close true
|
142
|
+
# end
|
143
|
+
#
|
144
|
+
# def self.start_daemon *args, &block
|
145
|
+
# :$VERBOSE.temporary nil do
|
146
|
+
# #EndData.close if $leftovers
|
147
|
+
# Process.fork do
|
148
|
+
# fork and exit
|
149
|
+
# trap( 'INT' ) { Thread.current.kill }
|
150
|
+
# $stderr = $stdout = $stdin = NullDevice.new
|
151
|
+
# Process.setsid
|
152
|
+
# block.call( *args )
|
153
|
+
# end
|
154
|
+
# end
|
155
|
+
# end
|
156
|
+
#
|
157
|
+
# def self.term_size
|
158
|
+
# require 'curses'
|
159
|
+
# Curses.init_screen
|
160
|
+
# x, y = Curses.cols, Curses.lines
|
161
|
+
# Curses.close_screen
|
162
|
+
# [x, y]
|
163
|
+
# ensure
|
164
|
+
# Curses.close_screen
|
165
|
+
# end
|
166
|
+
#
|
167
|
+
# def self.filename
|
168
|
+
# File.basename $0
|
169
|
+
# end
|
170
|
+
#
|
171
|
+
# def self.create_key size = 16 # copied from cgi/session.rb
|
172
|
+
# require 'digest/md5'
|
173
|
+
# md5 = Digest::MD5::new
|
174
|
+
# md5.update(String(Time::now))
|
175
|
+
# md5.update(String(rand(0)))
|
176
|
+
# md5.update(String($$))
|
177
|
+
# md5.hexdigest[0,size]
|
178
|
+
# end
|
179
|
+
#
|
180
|
+
#module Kernel
|
181
|
+
#
|
182
|
+
# def modules() self.class.modules end
|
183
|
+
# def module() self.class.module end
|
184
|
+
# def module_up() self.class.module_up end
|
185
|
+
# def modules_up() self.class.modules_up end
|
186
|
+
#
|
187
|
+
#end
|
188
|
+
#
|
189
|
+
#def required
|
190
|
+
# result = []
|
191
|
+
# $".each do |file|
|
192
|
+
# $:.each do |path|
|
193
|
+
# if File.exists?( path + '/' + file )
|
194
|
+
# result << (path + '/' + file)
|
195
|
+
# next
|
196
|
+
# end
|
197
|
+
# end
|
198
|
+
# end
|
199
|
+
# result
|
200
|
+
#end
|
201
|
+
#
|
202
|
+
#def required? file
|
203
|
+
# (el = required.grep( /#{file}(\.rb|\.so)?$/ ).to_el).empty? ? false : el
|
204
|
+
#end
|
205
|
+
#
|
206
|
+
#class Array
|
207
|
+
# def to_el # TODO better name
|
208
|
+
# size == 1 ? first : self
|
209
|
+
# end
|
210
|
+
#end
|
211
|
+
#
|
212
|
+
#class Numeric
|
213
|
+
# def commify
|
214
|
+
# to_s.reverse.scan(/\d{3}|\d+/).join(',').reverse
|
215
|
+
# end
|
216
|
+
#end
|
217
|
+
#
|
218
|
+
#class Float
|
219
|
+
# def to_s_cut x = 3
|
220
|
+
# to_s.scan(/\d*\.\d{0,#{x}}/)
|
221
|
+
# end
|
222
|
+
#end
|
data/lib/rextra/cutting.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class Object
|
2
|
-
def
|
3
|
-
def meta_eval(&blk)
|
2
|
+
def __meta() class << self; self end end
|
3
|
+
def meta_eval(&blk) __meta.instance_eval( &blk ) end
|
4
4
|
def meta_def(name, &blk) meta_eval { define_method name, &blk } end
|
5
5
|
def class_def name, &blk
|
6
6
|
self.class.class_eval { define_method name, &blk }
|
@@ -46,8 +46,7 @@ module Rextra
|
|
46
46
|
end
|
47
47
|
class Do < Base
|
48
48
|
def method_missing( sym, *args )
|
49
|
-
@master.map
|
50
|
-
self
|
49
|
+
@master.map do |e| e.send sym, *args end
|
51
50
|
end
|
52
51
|
def end() @master end
|
53
52
|
end
|
data/lib/rextra/enddata.rb
CHANGED
@@ -1,80 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# rextra/enddata.rb -
|
3
|
-
# USE "rdoc rextra/enddata.rb" to build the docs for this file.
|
4
|
-
#++
|
5
|
-
#
|
6
|
-
# == WARNING!
|
7
|
-
# load'ing or require'ing this file will write over anything in your DATA area
|
8
|
-
#
|
9
|
-
# == Example Use
|
10
|
-
# TBD
|
11
|
-
#
|
12
|
-
# == Credits
|
13
|
-
# Michael Garriss
|
14
|
-
#
|
15
|
-
# == Licence
|
16
|
-
# TBD
|
17
|
-
#
|
18
|
-
|
19
|
-
#--
|
20
|
-
# TODO review this
|
21
|
-
#++
|
22
|
-
|
23
|
-
require 'rextra'
|
24
|
-
|
25
|
-
module Rapid
|
26
|
-
|
27
|
-
class LEFTOVERS
|
28
|
-
class << self
|
29
|
-
strip_methods
|
30
|
-
def method_missing sym, *args
|
31
|
-
$leftovers.send sym, *args
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
module EndData
|
37
|
-
def self.add_tag
|
38
|
-
file = File.new $0, 'a+'
|
39
|
-
file << "\n__END__\n"
|
40
|
-
$_DATA = file # holy hack
|
41
|
-
end
|
42
|
-
if defined? DATA
|
43
|
-
$_DATA = DATA
|
44
|
-
else
|
45
|
-
self.add_tag
|
46
|
-
end
|
47
|
-
def self.make_writable( pos = $_DATA.pos )
|
48
|
-
$_DATA.reopen $0, 'a+'
|
49
|
-
$_DATA.pos = pos
|
50
|
-
end
|
51
|
-
def self.clear( pos = $_DATA.pos )
|
52
|
-
$_DATA.truncate pos
|
53
|
-
end
|
54
|
-
def self.write str
|
55
|
-
$_DATA.write str
|
56
|
-
end
|
57
|
-
def self.method_missing sym, *args
|
58
|
-
$_DATA.send sym, *args
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
pos = $_DATA.pos
|
63
|
-
if (m = $_DATA.read).size > 0
|
64
|
-
$leftovers = Marshal.load( m )
|
65
|
-
else
|
66
|
-
$leftovers = {}
|
67
|
-
end
|
68
|
-
begin
|
69
|
-
EndData.make_writable pos
|
70
|
-
at_exit do
|
71
|
-
unless EndData.closed?
|
72
|
-
EndData.clear pos
|
73
|
-
EndData.write Marshal.dump( $leftovers )
|
74
|
-
end
|
75
|
-
end
|
76
|
-
#rescue
|
77
|
-
end
|
78
|
-
|
79
|
-
end
|
80
|
-
|
data/test/tc_object.rb
CHANGED
metadata
CHANGED
@@ -3,13 +3,13 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: rextra
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 2.0.
|
7
|
-
date: 2006-
|
6
|
+
version: 2.0.3
|
7
|
+
date: 2006-11-02 00:00:00 -07:00
|
8
8
|
summary: Ruby extras.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
11
|
email: mgarriss@gmail.com
|
12
|
-
homepage:
|
12
|
+
homepage: http://crookedhideout.com
|
13
13
|
rubyforge_project:
|
14
14
|
description:
|
15
15
|
autorequire: rextra
|
@@ -35,7 +35,6 @@ files:
|
|
35
35
|
- test/ts_rextra.rb
|
36
36
|
- lib/rextra
|
37
37
|
- lib/rextra.rb
|
38
|
-
- lib/rextra/binding_of_caller.rb
|
39
38
|
- lib/rextra/bleeding.rb
|
40
39
|
- lib/rextra/cutting.rb
|
41
40
|
- lib/rextra/debug.rb
|
@@ -1,85 +0,0 @@
|
|
1
|
-
begin
|
2
|
-
require 'simplecc'
|
3
|
-
rescue LoadError
|
4
|
-
# to satisfy rdoc
|
5
|
-
class Continuation #:nodoc:
|
6
|
-
end
|
7
|
-
def Continuation.create(*args, &block) # :nodoc:
|
8
|
-
cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?}
|
9
|
-
result ||= args
|
10
|
-
return *[cc, *result]
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
class Binding; end # for RDoc
|
15
|
-
# This method returns the binding of the method that called your
|
16
|
-
# method. It will raise an Exception when you're not inside a method.
|
17
|
-
#
|
18
|
-
# It's used like this:
|
19
|
-
# def inc_counter(amount = 1)
|
20
|
-
# Binding.of_caller do |binding|
|
21
|
-
# # Create a lambda that will increase the variable 'counter'
|
22
|
-
# # in the caller of this method when called.
|
23
|
-
# inc = eval("lambda { |arg| counter += arg }", binding)
|
24
|
-
# # We can refer to amount from inside this block safely.
|
25
|
-
# inc.call(amount)
|
26
|
-
# end
|
27
|
-
# # No other statements can go here. Put them inside the block.
|
28
|
-
# end
|
29
|
-
# counter = 0
|
30
|
-
# 2.times { inc_counter }
|
31
|
-
# counter # => 2
|
32
|
-
#
|
33
|
-
# Binding.of_caller must be the last statement in the method.
|
34
|
-
# This means that you will have to put everything you want to
|
35
|
-
# do after the call to Binding.of_caller into the block of it.
|
36
|
-
# This should be no problem however, because Ruby has closures.
|
37
|
-
# If you don't do this an Exception will be raised. Because of
|
38
|
-
# the way that Binding.of_caller is implemented it has to be
|
39
|
-
# done this way.
|
40
|
-
def Binding.of_caller(&block)
|
41
|
-
old_critical = Thread.critical
|
42
|
-
Thread.critical = true
|
43
|
-
count = 0
|
44
|
-
cc, result, error, extra_data = Continuation.create(nil, nil)
|
45
|
-
error.call if error
|
46
|
-
|
47
|
-
tracer = lambda do |*args|
|
48
|
-
type, context, extra_data = args[0], args[4], args
|
49
|
-
if type == "return"
|
50
|
-
count += 1
|
51
|
-
# First this method and then calling one will return --
|
52
|
-
# the trace event of the second event gets the context
|
53
|
-
# of the method which called the method that called this
|
54
|
-
# method.
|
55
|
-
if count == 2
|
56
|
-
# It would be nice if we could restore the trace_func
|
57
|
-
# that was set before we swapped in our own one, but
|
58
|
-
# this is impossible without overloading set_trace_func
|
59
|
-
# in current Ruby.
|
60
|
-
set_trace_func(nil)
|
61
|
-
cc.call(eval("binding", context), nil, extra_data)
|
62
|
-
end
|
63
|
-
elsif type == "line" then
|
64
|
-
nil
|
65
|
-
elsif type == "c-return" and extra_data[3] == :set_trace_func then
|
66
|
-
nil
|
67
|
-
else
|
68
|
-
set_trace_func(nil)
|
69
|
-
error_msg = "Binding.of_caller used in non-method context or " +
|
70
|
-
"trailing statements of method using it aren't in the block."
|
71
|
-
cc.call(nil, lambda { raise(ArgumentError, error_msg) }, nil)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
unless result
|
76
|
-
set_trace_func(tracer)
|
77
|
-
return nil
|
78
|
-
else
|
79
|
-
Thread.critical = old_critical
|
80
|
-
case block.arity
|
81
|
-
when 1 then yield(result)
|
82
|
-
else yield(result, extra_data)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|