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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
# frozen_string_literal: false
#
# irb/workspace-binding.rb -
# $Release Version: 0.9.6$
# $Revision$
# by Keiju ISHITSUKA([email protected])
#
# --
#
#
#
module IRB # :nodoc:
class WorkSpace
# Creates a new workspace.
#
# set self to main if specified, otherwise
# inherit main from TOPLEVEL_BINDING.
def initialize(*main)
if main[0].kind_of?(Binding)
@binding = main.shift
elsif IRB.conf[:SINGLE_IRB]
@binding = TOPLEVEL_BINDING
else
case IRB.conf[:CONTEXT_MODE]
when 0 # binding in proc on TOPLEVEL_BINDING
@binding = eval("proc{binding}.call",
TOPLEVEL_BINDING,
__FILE__,
__LINE__)
when 1 # binding in loaded file
require "tempfile"
f = Tempfile.open("irb-binding")
f.print <<EOF
$binding = binding
EOF
f.close
load f.path
@binding = $binding
when 2 # binding in loaded file(thread use)
unless defined? BINDING_QUEUE
IRB.const_set(:BINDING_QUEUE, Thread::SizedQueue.new(1))
Thread.abort_on_exception = true
Thread.start do
eval "require \"irb/ws-for-case-2\"", TOPLEVEL_BINDING, __FILE__, __LINE__
end
Thread.pass
end
@binding = BINDING_QUEUE.pop
when 3 # binding in function on TOPLEVEL_BINDING(default)
@binding = eval("def irb_binding; private; binding; end; irb_binding",
TOPLEVEL_BINDING,
__FILE__,
__LINE__ - 3)
end
end
if main.empty?
@main = eval("self", @binding)
else
@main = main[0]
IRB.conf[:__MAIN__] = @main
case @main
when Module
@binding = eval("IRB.conf[:__MAIN__].module_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
else
begin
@binding = eval("IRB.conf[:__MAIN__].instance_eval('binding', __FILE__, __LINE__)", @binding, __FILE__, __LINE__)
rescue TypeError
IRB.fail CantChangeBinding, @main.inspect
end
end
end
eval("_=nil", @binding)
end
# The Binding of this workspace
attr_reader :binding
# The top-level workspace of this context, also available as
# <code>IRB.conf[:__MAIN__]</code>
attr_reader :main
# Evaluate the given +statements+ within the context of this workspace.
def evaluate(context, statements, file = __FILE__, line = __LINE__)
eval(statements, @binding, file, line)
end
# error message manipulator
def filter_backtrace(bt)
case IRB.conf[:CONTEXT_MODE]
when 0
return nil if bt =~ /\(irb_local_binding\)/
when 1
if(bt =~ %r!/tmp/irb-binding! or
bt =~ %r!irb/.*\.rb! or
bt =~ /irb\.rb/)
return nil
end
when 2
return nil if bt =~ /irb\/.*\.rb/
return nil if bt =~ /irb\.rb/
when 3
return nil if bt =~ /irb\/.*\.rb/
return nil if bt =~ /irb\.rb/
bt = bt.sub(/:\s*in `irb_binding'/, '')
end
bt
end
def code_around_binding
file, pos = @binding.source_location
unless defined?(::SCRIPT_LINES__[file]) && lines = ::SCRIPT_LINES__[file]
begin
lines = File.readlines(file)
rescue SystemCallError
return
end
end
pos -= 1
start_pos = [pos - 5, 0].max
end_pos = [pos + 5, lines.size - 1].min
fmt = " %2s %#{end_pos.to_s.length}d: %s"
body = (start_pos..end_pos).map do |current_pos|
sprintf(fmt, pos == current_pos ? '=>' : '', current_pos + 1, lines[current_pos])
end.join("")
"\nFrom: #{file} @ line #{pos + 1} :\n\n#{body}\n"
end
def IRB.delete_caller
end
end
end
|