pry 0.9.7.4-i386-mswin32 → 0.9.8-i386-mswin32
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 +2 -3
- data/CHANGELOG +43 -0
- data/README.markdown +3 -1
- data/Rakefile +51 -32
- data/bin/pry +2 -80
- data/lib/pry.rb +33 -26
- data/lib/pry/cli.rb +152 -0
- data/lib/pry/code.rb +351 -0
- data/lib/pry/command.rb +422 -0
- data/lib/pry/command_set.rb +259 -129
- data/lib/pry/commands.rb +0 -1
- data/lib/pry/config.rb +43 -9
- data/lib/pry/default_commands/context.rb +109 -92
- data/lib/pry/default_commands/documentation.rb +174 -63
- data/lib/pry/default_commands/easter_eggs.rb +26 -2
- data/lib/pry/default_commands/gems.rb +65 -37
- data/lib/pry/default_commands/input.rb +175 -243
- data/lib/pry/default_commands/introspection.rb +173 -112
- data/lib/pry/default_commands/ls.rb +96 -114
- data/lib/pry/default_commands/shell.rb +175 -70
- data/lib/pry/helpers/base_helpers.rb +7 -2
- data/lib/pry/helpers/command_helpers.rb +71 -77
- data/lib/pry/helpers/options_helpers.rb +10 -41
- data/lib/pry/helpers/text.rb +24 -4
- data/lib/pry/history.rb +55 -17
- data/lib/pry/history_array.rb +2 -0
- data/lib/pry/hooks.rb +252 -0
- data/lib/pry/indent.rb +9 -5
- data/lib/pry/method.rb +149 -50
- data/lib/pry/plugins.rb +12 -4
- data/lib/pry/pry_class.rb +69 -26
- data/lib/pry/pry_instance.rb +187 -115
- data/lib/pry/version.rb +1 -1
- data/lib/pry/wrapped_module.rb +73 -0
- data/man/pry.1 +195 -0
- data/man/pry.1.html +204 -0
- data/man/pry.1.ronn +141 -0
- data/pry.gemspec +29 -32
- data/test/helper.rb +32 -36
- data/test/test_cli.rb +78 -0
- data/test/test_code.rb +201 -0
- data/test/test_command.rb +327 -0
- data/test/test_command_integration.rb +512 -0
- data/test/test_command_set.rb +338 -12
- data/test/test_completion.rb +1 -1
- data/test/test_default_commands.rb +1 -2
- data/test/test_default_commands/test_context.rb +27 -5
- data/test/test_default_commands/test_documentation.rb +20 -8
- data/test/test_default_commands/test_input.rb +84 -45
- data/test/test_default_commands/test_introspection.rb +74 -17
- data/test/test_default_commands/test_ls.rb +9 -36
- data/test/test_default_commands/test_shell.rb +240 -13
- data/test/test_hooks.rb +490 -0
- data/test/test_indent.rb +2 -0
- data/test/test_method.rb +60 -0
- data/test/test_pry.rb +29 -904
- data/test/test_pry_defaults.rb +380 -0
- data/test/test_pry_history.rb +24 -24
- data/test/test_syntax_checking.rb +63 -0
- data/test/test_wrapped_module.rb +71 -0
- metadata +50 -39
- data/lib/pry/command_context.rb +0 -53
- data/lib/pry/command_processor.rb +0 -181
- data/lib/pry/extended_commands/user_command_api.rb +0 -65
- data/test/test_command_processor.rb +0 -176
@@ -28,104 +28,209 @@ class Pry
|
|
28
28
|
_pry_.instance_eval(&Pry::FILE_COMPLETIONS)
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
32
31
|
alias_command "file-mode", "shell-mode"
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
create_command "save-file", "Export to a file using content from the REPL." do
|
34
|
+
banner <<-USAGE
|
35
|
+
Usage: save-file [OPTIONS] [FILE]
|
36
|
+
Save REPL content to a file.
|
37
|
+
e.g: save-file -m my_method -m my_method2 ./hello.rb
|
38
|
+
e.g: save-file -i 1..10 ./hello.rb --append
|
39
|
+
e.g: save-file -c show-method ./my_command.rb
|
40
|
+
e.g: save-file -f sample_file --lines 2..10 ./output_file.rb
|
41
|
+
USAGE
|
42
|
+
|
43
|
+
attr_accessor :content
|
44
|
+
attr_accessor :file_name
|
45
|
+
|
46
|
+
def setup
|
47
|
+
self.content = ""
|
48
|
+
end
|
39
49
|
|
40
|
-
|
41
|
-
opt.on :
|
42
|
-
|
50
|
+
def options(opt)
|
51
|
+
opt.on :m, :method, "Save a method's source.", true do |meth_name|
|
52
|
+
meth = get_method_or_raise(meth_name, target, {})
|
53
|
+
self.content << meth.source
|
54
|
+
end
|
55
|
+
opt.on :c, :command, "Save a command's source.", true do |command_name|
|
56
|
+
command = find_command(command_name)
|
57
|
+
block = Pry::Method.new(find_command(command_name).block)
|
58
|
+
self.content << block.source
|
59
|
+
end
|
60
|
+
opt.on :f, :file, "Save a file.", true do |file|
|
61
|
+
self.content << File.read(File.expand_path(file))
|
43
62
|
end
|
63
|
+
opt.on :l, :lines, "Only save a subset of lines.", :optional => true, :as => Range, :default => 1..-1
|
64
|
+
opt.on :i, :in, "Save entries from Pry's input expression history. Takes an index or range.", :optional => true,
|
65
|
+
:as => Range, :default => -5..-1 do |range|
|
66
|
+
input_expressions = _pry_.input_array[range] || []
|
67
|
+
Array(input_expressions).each { |v| self.content << v }
|
68
|
+
end
|
69
|
+
opt.on :a, :append, "Append to the given file instead of overwriting it."
|
70
|
+
end
|
44
71
|
|
45
|
-
|
46
|
-
|
72
|
+
def process
|
73
|
+
if args.empty?
|
74
|
+
raise CommandError, "Must specify a file name."
|
47
75
|
end
|
48
76
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
start_line = start_line < 0 ? 0 : start_line
|
63
|
-
end_line = (ex_line - 1) + window_size
|
64
|
-
if ex_file && RbxPath.is_core_path?(ex_file)
|
65
|
-
file_name = RbxPath.convert_path_to_full(ex_file)
|
77
|
+
self.file_name = File.expand_path(args.first)
|
78
|
+
|
79
|
+
save_file
|
80
|
+
end
|
81
|
+
|
82
|
+
def save_file
|
83
|
+
if self.content.empty?
|
84
|
+
raise CommandError, "Found no code to save."
|
85
|
+
end
|
86
|
+
|
87
|
+
File.open(file_name, mode) do |f|
|
88
|
+
if opts.present?(:lines)
|
89
|
+
f.puts restrict_to_lines(content, opts[:l])
|
66
90
|
else
|
67
|
-
|
91
|
+
f.puts content
|
68
92
|
end
|
69
93
|
end
|
94
|
+
end
|
70
95
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
96
|
+
def mode
|
97
|
+
if opts.present?(:append)
|
98
|
+
"a"
|
99
|
+
else
|
100
|
+
"w"
|
76
101
|
end
|
77
102
|
end
|
103
|
+
end
|
78
104
|
|
79
|
-
|
105
|
+
create_command "cat", "Show code from a file, Pry's input buffer, or the last exception." do
|
106
|
+
banner <<-USAGE
|
107
|
+
Usage: cat FILE
|
108
|
+
cat --ex [STACK_INDEX]
|
109
|
+
cat --in [INPUT_INDEX_OR_RANGE]
|
80
110
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
111
|
+
cat is capable of showing part or all of a source file, the context of the
|
112
|
+
last exception, or an expression from Pry's input history.
|
113
|
+
|
114
|
+
cat --ex defaults to showing the lines surrounding the location of the last
|
115
|
+
exception. Invoking it more than once travels up the exception's backtrace,
|
116
|
+
and providing a number shows the context of the given index of the backtrace.
|
117
|
+
USAGE
|
88
118
|
|
89
|
-
|
90
|
-
|
119
|
+
def options(opt)
|
120
|
+
opt.on :ex, "Show the context of the last exception.", :optional => true, :as => Integer
|
121
|
+
opt.on :i, :in, "Show one or more entries from Pry's expression history.", :optional => true, :as => Range, :default => -5..-1
|
122
|
+
|
123
|
+
opt.on :s, :start, "Starting line (defaults to the first line).", :optional => true, :as => Integer
|
124
|
+
opt.on :e, :end, "Ending line (defaults to the last line).", :optional => true, :as => Integer
|
125
|
+
opt.on :l, :'line-numbers', "Show line numbers."
|
126
|
+
opt.on :t, :type, "The file type for syntax highlighting (e.g., 'ruby' or 'python').", true, :as => Symbol
|
127
|
+
|
128
|
+
opt.on :f, :flood, "Do not use a pager to view text longer than one screen."
|
91
129
|
end
|
92
130
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
131
|
+
def process
|
132
|
+
handler = case
|
133
|
+
when opts.present?(:ex)
|
134
|
+
method :process_ex
|
135
|
+
when opts.present?(:in)
|
136
|
+
method :process_in
|
137
|
+
else
|
138
|
+
method :process_file
|
139
|
+
end
|
140
|
+
|
141
|
+
output = handler.call do |code|
|
142
|
+
code.code_type = opts[:type] || :ruby
|
143
|
+
|
144
|
+
code.between(opts[:start] || 1, opts[:end] || -1).
|
145
|
+
with_line_numbers(opts.present?(:'line-numbers') || opts.present?(:ex))
|
146
|
+
end
|
147
|
+
|
148
|
+
render_output(output, opts)
|
98
149
|
end
|
99
150
|
|
100
|
-
|
101
|
-
|
151
|
+
def process_ex
|
152
|
+
window_size = Pry.config.default_window_size || 5
|
153
|
+
ex = _pry_.last_exception
|
154
|
+
|
155
|
+
raise CommandError, "No exception found." unless ex
|
156
|
+
|
157
|
+
if opts[:ex].nil?
|
158
|
+
bt_index = ex.bt_index
|
159
|
+
ex.inc_bt_index
|
160
|
+
else
|
161
|
+
bt_index = opts[:ex]
|
162
|
+
end
|
163
|
+
|
164
|
+
ex_file, ex_line = ex.bt_source_location_for(bt_index)
|
165
|
+
|
166
|
+
raise CommandError, "The given backtrace level is out of bounds." unless ex_file
|
167
|
+
|
168
|
+
if RbxPath.is_core_path?(ex_file)
|
169
|
+
ex_file = RbxPath.convert_path_to_full(ex_file)
|
170
|
+
end
|
171
|
+
|
172
|
+
set_file_and_dir_locals(ex_file)
|
173
|
+
|
174
|
+
start_line = ex_line - window_size
|
175
|
+
start_line = 1 if start_line < 1
|
176
|
+
end_line = ex_line + window_size
|
177
|
+
|
178
|
+
header = unindent <<-HEADER
|
179
|
+
#{text.bold 'Exception:'} #{ex.class}: #{ex.message}
|
180
|
+
--
|
181
|
+
#{text.bold('From:')} #{ex_file} @ line #{ex_line} @ #{text.bold("level: #{bt_index}")} of backtrace (of #{ex.backtrace.size - 1}).
|
182
|
+
|
183
|
+
HEADER
|
184
|
+
|
185
|
+
code = yield(Pry::Code.from_file(ex_file).
|
186
|
+
between(start_line, end_line).
|
187
|
+
with_marker(ex_line))
|
188
|
+
|
189
|
+
"#{header}#{code}"
|
102
190
|
end
|
103
191
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
contents = text.with_line_numbers contents, start_line + 1, :bright_red
|
192
|
+
def process_in
|
193
|
+
normalized_range = absolute_index_range(opts[:i], _pry_.input_array.length)
|
194
|
+
input_items = _pry_.input_array[normalized_range] || []
|
108
195
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
196
|
+
zipped_items = normalized_range.zip(input_items).reject { |_, s| s.nil? || s == "" }
|
197
|
+
|
198
|
+
unless zipped_items.length > 0
|
199
|
+
raise CommandError, "No expressions found."
|
200
|
+
end
|
201
|
+
|
202
|
+
if zipped_items.length > 1
|
203
|
+
contents = ""
|
204
|
+
zipped_items.each do |i, s|
|
205
|
+
contents << "#{text.bold(i.to_s)}:\n"
|
206
|
+
contents << yield(Pry::Code(s).with_indentation(2)).to_s
|
115
207
|
end
|
116
|
-
|
208
|
+
else
|
209
|
+
contents = yield(Pry::Code(zipped_items.first.last))
|
210
|
+
end
|
117
211
|
|
118
|
-
|
119
|
-
output.puts "\n#{Pry::Helpers::Text.bold('Exception:')} #{_pry_.last_exception.class}: #{_pry_.last_exception.message}\n--"
|
120
|
-
output.puts "#{Pry::Helpers::Text.bold('From:')} #{ex_file} @ line #{ex_line} @ #{text.bold('level: ')} #{bt_index} of backtrace (of #{_pry_.last_exception.backtrace.size - 1}).\n\n"
|
212
|
+
contents
|
121
213
|
end
|
122
214
|
|
123
|
-
|
215
|
+
def process_file
|
216
|
+
file_name = args.shift
|
217
|
+
|
218
|
+
unless file_name
|
219
|
+
raise CommandError, "Must provide a filename, --in, or --ex."
|
220
|
+
end
|
221
|
+
|
222
|
+
file_name, line_num = file_name.split(':')
|
223
|
+
file_name = File.expand_path(file_name)
|
224
|
+
set_file_and_dir_locals(file_name)
|
124
225
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
226
|
+
code = yield(Pry::Code.from_file(file_name))
|
227
|
+
|
228
|
+
if line_num
|
229
|
+
code = code.around(line_num.to_i,
|
230
|
+
Pry.config.default_window_size || 7)
|
231
|
+
end
|
232
|
+
|
233
|
+
code
|
129
234
|
end
|
130
235
|
end
|
131
236
|
end
|
@@ -91,14 +91,19 @@ class Pry
|
|
91
91
|
27
|
92
92
|
end
|
93
93
|
|
94
|
+
# have fun on the Windows platform.
|
95
|
+
def windows?
|
96
|
+
RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
|
97
|
+
end
|
98
|
+
|
94
99
|
# are we on Jruby platform?
|
95
100
|
def jruby?
|
96
|
-
|
101
|
+
RbConfig::CONFIG['ruby_install_name'] == 'jruby'
|
97
102
|
end
|
98
103
|
|
99
104
|
# are we on rbx platform?
|
100
105
|
def rbx?
|
101
|
-
|
106
|
+
RbConfig::CONFIG['ruby_install_name'] == 'rbx'
|
102
107
|
end
|
103
108
|
|
104
109
|
# a simple pager for systems without `less`. A la windows.
|
@@ -6,26 +6,21 @@ class Pry
|
|
6
6
|
|
7
7
|
module_function
|
8
8
|
|
9
|
-
# if start_line is not false then add line numbers starting with start_line
|
10
|
-
def render_output(should_flood, start_line, text, color=:blue)
|
11
|
-
if start_line
|
12
|
-
text = Pry::Helpers::Text.with_line_numbers text, start_line, color
|
13
|
-
end
|
14
|
-
|
15
|
-
if should_flood
|
16
|
-
output.puts text
|
17
|
-
else
|
18
|
-
stagger_output(text)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
9
|
# Open a temp file and yield it to the block, closing it after
|
23
10
|
# @return [String] The path of the temp file
|
24
|
-
def temp_file
|
25
|
-
file = Tempfile.new([
|
11
|
+
def temp_file(ext='.rb')
|
12
|
+
file = Tempfile.new(['pry', ext])
|
26
13
|
yield file
|
27
14
|
ensure
|
28
|
-
file.close
|
15
|
+
file.close(true) if file
|
16
|
+
end
|
17
|
+
|
18
|
+
def render_output(str, opts={})
|
19
|
+
if opts[:flood]
|
20
|
+
output.puts str
|
21
|
+
else
|
22
|
+
stagger_output str
|
23
|
+
end
|
29
24
|
end
|
30
25
|
|
31
26
|
def get_method_or_raise(name, target, opts={}, omit_help=false)
|
@@ -34,14 +29,14 @@ class Pry
|
|
34
29
|
if name && !meth
|
35
30
|
command_error("The method '#{name}' could not be found.", omit_help)
|
36
31
|
elsif !meth
|
37
|
-
command_error("No method name given, and context is not a method.", omit_help)
|
32
|
+
command_error("No method name given, and context is not a method.", omit_help, NonMethodContextError)
|
38
33
|
end
|
39
34
|
|
40
35
|
(opts[:super] || 0).times do
|
41
36
|
if meth.super
|
42
37
|
meth = meth.super
|
43
38
|
else
|
44
|
-
command_error("
|
39
|
+
command_error("'#{meth.name_with_owner}' has no super method.", omit_help)
|
45
40
|
end
|
46
41
|
end
|
47
42
|
|
@@ -49,9 +44,9 @@ class Pry
|
|
49
44
|
meth
|
50
45
|
end
|
51
46
|
|
52
|
-
def command_error(message, omit_help)
|
47
|
+
def command_error(message, omit_help, klass=CommandError)
|
53
48
|
message += " Type `#{command_name} --help` for help." unless omit_help
|
54
|
-
raise
|
49
|
+
raise klass, message
|
55
50
|
end
|
56
51
|
|
57
52
|
def make_header(meth, content=meth.source)
|
@@ -66,60 +61,6 @@ class Pry
|
|
66
61
|
header << "#{Pry::Helpers::Text.bold("Number of lines:")} #{content.each_line.count.to_s}\n"
|
67
62
|
end
|
68
63
|
|
69
|
-
def file_map
|
70
|
-
{
|
71
|
-
[".c", ".h"] => :c,
|
72
|
-
[".cpp", ".hpp", ".cc", ".h", "cxx"] => :cpp,
|
73
|
-
[".rb", "Rakefile", ".irbrc", ".gemspec", ".pryrc"] => :ruby,
|
74
|
-
".py" => :python,
|
75
|
-
".diff" => :diff,
|
76
|
-
".css" => :css,
|
77
|
-
".html" => :html,
|
78
|
-
[".yaml", ".yml"] => :yaml,
|
79
|
-
".xml" => :xml,
|
80
|
-
".php" => :php,
|
81
|
-
".js" => :javascript,
|
82
|
-
".java" => :java,
|
83
|
-
".rhtml" => :rhtml,
|
84
|
-
".json" => :json
|
85
|
-
}
|
86
|
-
end
|
87
|
-
|
88
|
-
def syntax_highlight_by_file_type_or_specified(contents, file_name, file_type)
|
89
|
-
_, language_detected = file_map.find do |k, v|
|
90
|
-
Array(k).any? do |matcher|
|
91
|
-
matcher == File.extname(file_name) || matcher == File.basename(file_name)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
language_detected = file_type if file_type
|
96
|
-
if Pry.color
|
97
|
-
CodeRay.scan(contents, language_detected).term
|
98
|
-
else
|
99
|
-
contents
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# convert negative line numbers to positive by wrapping around
|
104
|
-
# last line (as per array indexing with negative numbers)
|
105
|
-
def normalized_line_number(line_number, total_lines)
|
106
|
-
line_number < 0 ? line_number + total_lines : line_number
|
107
|
-
end
|
108
|
-
|
109
|
-
# returns the file content between the lines and the normalized
|
110
|
-
# start and end line numbers.
|
111
|
-
def read_between_the_lines(file_name, start_line, end_line)
|
112
|
-
if file_name == Pry.eval_path
|
113
|
-
content = Pry.line_buffer.drop(1).join
|
114
|
-
else
|
115
|
-
content = File.read(File.expand_path(file_name))
|
116
|
-
end
|
117
|
-
lines_array = content.each_line.to_a
|
118
|
-
|
119
|
-
[lines_array[start_line..end_line].join, normalized_line_number(start_line, lines_array.size),
|
120
|
-
normalized_line_number(end_line, lines_array.size)]
|
121
|
-
end
|
122
|
-
|
123
64
|
def process_rdoc(comment, code_type)
|
124
65
|
comment = comment.dup
|
125
66
|
comment.gsub(/<code>(?:\s*\n)?(.*?)\s*<\/code>/m) { Pry.color ? CodeRay.scan($1, code_type).term : $1 }.
|
@@ -157,6 +98,7 @@ class Pry
|
|
157
98
|
end
|
158
99
|
|
159
100
|
def invoke_editor(file, line)
|
101
|
+
raise CommandError, "Please set Pry.config.editor or export $EDITOR" unless Pry.config.editor
|
160
102
|
if Pry.config.editor.respond_to?(:call)
|
161
103
|
editor_invocation = Pry.config.editor.call(file, line)
|
162
104
|
else
|
@@ -176,14 +118,16 @@ class Pry
|
|
176
118
|
# Note we dont want to use Pry.config.system here as that
|
177
119
|
# may be invoked non-interactively (i.e via Open4), whereas we want to
|
178
120
|
# ensure the editor is always interactive
|
179
|
-
system(editor_invocation)
|
121
|
+
system(editor_invocation) or raise CommandError, "`#{editor_invocation}` gave exit status: #{$?.exitstatus}"
|
180
122
|
end
|
181
123
|
end
|
182
124
|
|
183
125
|
# Return the syntax for a given editor for starting the editor
|
184
126
|
# and moving to a particular line within that file
|
185
127
|
def start_line_syntax_for_editor(file_name, line_number)
|
186
|
-
|
128
|
+
if windows?
|
129
|
+
file_name = file_name.gsub(/\//, '\\')
|
130
|
+
end
|
187
131
|
|
188
132
|
# special case for 1st line
|
189
133
|
return file_name if line_number <= 1
|
@@ -198,7 +142,7 @@ class Pry
|
|
198
142
|
when /^jedit/
|
199
143
|
"#{file_name} +line:#{line_number}"
|
200
144
|
else
|
201
|
-
if
|
145
|
+
if windows?
|
202
146
|
"#{file_name}"
|
203
147
|
else
|
204
148
|
"+#{line_number} #{file_name}"
|
@@ -247,6 +191,56 @@ class Pry
|
|
247
191
|
text.gsub(/^#{margin}/, '')
|
248
192
|
end
|
249
193
|
|
194
|
+
# Restrict a string to the given range of lines (1-indexed)
|
195
|
+
# @param [String] content The string.
|
196
|
+
# @param [Range, Fixnum] lines The line(s) to restrict it to.
|
197
|
+
# @return [String] The resulting string.
|
198
|
+
def restrict_to_lines(content, lines)
|
199
|
+
line_range = one_index_range_or_number(lines)
|
200
|
+
Array(content.lines.to_a[line_range]).join
|
201
|
+
end
|
202
|
+
|
203
|
+
def one_index_number(line_number)
|
204
|
+
if line_number > 0
|
205
|
+
line_number - 1
|
206
|
+
else
|
207
|
+
line_number
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# convert a 1-index range to a 0-indexed one
|
212
|
+
def one_index_range(range)
|
213
|
+
Range.new(one_index_number(range.begin), one_index_number(range.end))
|
214
|
+
end
|
215
|
+
|
216
|
+
def one_index_range_or_number(range_or_number)
|
217
|
+
case range_or_number
|
218
|
+
when Range
|
219
|
+
one_index_range(range_or_number)
|
220
|
+
else
|
221
|
+
one_index_number(range_or_number)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def absolute_index_number(line_number, array_length)
|
226
|
+
if line_number >= 0
|
227
|
+
line_number
|
228
|
+
else
|
229
|
+
[array_length + line_number, 0].max
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
def absolute_index_range(range_or_number, array_length)
|
234
|
+
case range_or_number
|
235
|
+
when Range
|
236
|
+
a = absolute_index_number(range_or_number.begin, array_length)
|
237
|
+
b = absolute_index_number(range_or_number.end, array_length)
|
238
|
+
else
|
239
|
+
a = b = absolute_index_number(range_or_number, array_length)
|
240
|
+
end
|
241
|
+
|
242
|
+
Range.new(a, b)
|
243
|
+
end
|
250
244
|
end
|
251
245
|
|
252
246
|
end
|