Class: Pry::Code
Overview
Pry::Code is a class that encapsulates lines of source code and their
line numbers and formats them for terminal output. It can read from a file
or method definition or be instantiated with a String or an Array.
In general, the formatting methods in Code return a new Code object
which will format the text as specified when #to_s is called. This allows
arbitrary chaining of formatting methods without mutating the original
object.
Instance Attribute Summary (collapse)
-
- (Object) code_type
Returns the value of attribute code_type.
Class Method Summary (collapse)
-
+ (Boolean) complete_expression?(str)
Determine if a string of code is a complete Ruby expression.
-
+ (Code) from_file(fn, code_type = nil)
Instantiate a
Codeobject containing code loaded from a file or Pry's line buffer. -
+ (Code) from_method(meth, start_line = nil)
Instantiate a
Codeobject containing code extracted from a::Method,UnboundMethod,Proc, orPry::Methodobject. -
+ (Code) from_module(mod, start_line = nil)
Attempt to extract the source code for module (or class)
mod. -
+ (Boolean) incomplete_user_input_exception?(ex)
private
Check whether the exception indicates that the user should input more.
-
+ (String?) retrieve_complete_expression_from(str_or_lines)
Retrieve the first complete expression from the passed string.
Instance Method Summary (collapse)
-
- (Boolean) ==(other)
Two
Codeobjects are equal if they contain the same lines with the same numbers. -
- (Code) after(line_num, lines = 1)
Remove all lines except for the
linesafter and excludingline_num. -
- (Code) around(line_num, lines = 1)
Remove all lines except for the
lineson either side of and includingline_num. -
- (Code) before(line_num, lines = 1)
Remove all lines except for the
linesup to and excludingline_num. -
- (Code) between(start_line, end_line = nil)
Remove all lines that aren't in the given range, expressed either as a
Rangeobject or a first and last line number (inclusive). -
- (Code) grep(pattern)
Remove all lines that don't match the given
pattern. -
- (Code) initialize(lines = [], start_line = 1, code_type = :ruby)
constructor
Instantiate a
Codeobject containing code from the givenArray,String, orIO. - - (String) inspect
-
- (Fixnum) length
Return the number of lines stored.
-
- (Object) method_missing(name, *args, &blk)
Forward any missing methods to the output of
#to_s. -
- (String) push(line, line_num = nil)
(also: #<<)
Append the given line.
-
- (String) raw
Return an unformatted String of the code.
-
- (Code) select {|line| ... }
Filter the lines using the given block.
-
- (Code) take_lines(start_line, num_lines)
Take
num_linesfromstart_line, forward or backwards. -
- (String) to_s
Based on the configuration of the object, return a formatted String representation.
-
- (Code) with_indentation(spaces = 0)
Format output with the specified number of spaces in front of every line, unless
spacesis falsy. -
- (Code) with_line_numbers(y_n = true)
Format output with line numbers next to it, unless
y_nis falsy. -
- (Code) with_marker(line_num = 1)
Format output with a marker next to the given
line_num, unlessline_numis falsy.
Constructor Details
- (Code) initialize(lines = [], start_line = 1, code_type = :ruby)
Instantiate a Code object containing code from the given Array,
String, or IO. The first line will be line 1 unless specified
otherwise. If you need non-contiguous line numbers, you can create an
empty Code object and then use #push to insert the lines.
184 185 186 187 188 189 190 191 |
# File 'lib/pry/code.rb', line 184 def initialize(lines=[], start_line=1, code_type=:ruby) if lines.is_a? String lines = lines.lines end @lines = lines.each_with_index.map { |l, i| [l.chomp, i + start_line.to_i] } @code_type = code_type end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
- (Object) method_missing(name, *args, &blk)
Forward any missing methods to the output of #to_s.
432 433 434 |
# File 'lib/pry/code.rb', line 432 def method_missing(name, *args, &blk) to_s.send(name, *args, &blk) end |
Instance Attribute Details
- (Object) code_type
Returns the value of attribute code_type
174 175 176 |
# File 'lib/pry/code.rb', line 174 def code_type @code_type end |
Class Method Details
+ (Boolean) complete_expression?(str)
Determine if a string of code is a complete Ruby expression.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/pry/code.rb', line 38 def complete_expression?(str) if defined?(Rubinius::Melbourne19) && RUBY_VERSION =~ /^1\.9/ Rubinius::Melbourne19.parse_string(str, Pry.eval_path) elsif defined?(Rubinius::Melbourne) Rubinius::Melbourne.parse_string(str, Pry.eval_path) else catch(:valid) do Helpers::BaseHelpers.silence_warnings do eval("BEGIN{throw :valid}\n#{str}", binding, Pry.eval_path) end end end # Assert that a line which ends with a , or \ is incomplete. str !~ /[,\\]\s*\z/ rescue SyntaxError => e if incomplete_user_input_exception?(e) false else raise e end end |
+ (Code) from_file(fn, code_type = nil)
Instantiate a Code object containing code loaded from a file or
Pry's line buffer.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/pry/code.rb', line 102 def from_file(fn, code_type=nil) if fn == Pry.eval_path f = Pry.line_buffer.drop(1) else if File.readable?(fn) f = File.open(fn, 'r') code_type = type_from_filename(fn) else raise CommandError, "Cannot open #{fn.inspect} for reading." end end new(f, 1, code_type || :ruby) ensure f.close if f.respond_to?(:close) end |
+ (Code) from_method(meth, start_line = nil)
Instantiate a Code object containing code extracted from a
::Method, UnboundMethod, Proc, or Pry::Method object.
126 127 128 129 130 |
# File 'lib/pry/code.rb', line 126 def from_method(meth, start_line=nil) meth = Pry::Method(meth) start_line ||= meth.source_line || 1 new(meth.source, start_line, meth.source_type) end |
+ (Code) from_module(mod, start_line = nil)
Attempt to extract the source code for module (or class) mod.
136 137 138 139 140 |
# File 'lib/pry/code.rb', line 136 def from_module(mod, start_line=nil) mod = Pry::WrappedModule(mod) start_line ||= mod.source_line || 1 new(mod.source, start_line, :ruby) end |
+ (Boolean) incomplete_user_input_exception?(ex) (private)
Check whether the exception indicates that the user should input more.
67 68 69 70 71 72 73 74 75 76 |
# File 'lib/pry/code.rb', line 67 def incomplete_user_input_exception?(ex) case ex. when /unexpected (\$end|end-of-file|END_OF_FILE)/, # mri, jruby, ironruby /unterminated (quoted string|string|regexp) meets end of file/, # "quoted string" is ironruby /missing 'end' for/, /: expecting '[})\]]'$/, /can't find string ".*" anywhere before EOF/, /: expecting keyword_end/, /expecting kWHEN/ # rbx true else false end end |
+ (String?) retrieve_complete_expression_from(str_or_lines)
Retrieve the first complete expression from the passed string.
85 86 87 88 89 90 91 92 93 94 |
# File 'lib/pry/code.rb', line 85 def retrieve_complete_expression_from(str_or_lines) lines = str_or_lines.is_a?(Array) ? str_or_lines : str_or_lines.each_line.to_a code = "" lines.each do |v| code << v return code if complete_expression?(code) end nil end |
Instance Method Details
- (Boolean) ==(other)
Two Code objects are equal if they contain the same lines with the same
numbers. Otherwise, call to_s and chomp and compare as Strings.
420 421 422 423 424 425 426 427 428 429 |
# File 'lib/pry/code.rb', line 420 def ==(other) if other.is_a?(Code) @other_lines = other.instance_variable_get(:@lines) @lines.each_with_index.all? do |(l, ln), i| l == @other_lines[i].first && ln == @other_lines[i].last end else to_s.chomp == other.to_s.chomp end end |
- (Code) after(line_num, lines = 1)
Remove all lines except for the lines after and excluding line_num.
301 302 303 304 305 306 307 |
# File 'lib/pry/code.rb', line 301 def after(line_num, lines=1) return self unless line_num select do |l, ln| ln > line_num && ln <= line_num + lines end end |
- (Code) around(line_num, lines = 1)
Remove all lines except for the lines on either side of and including
line_num.
288 289 290 291 292 293 294 |
# File 'lib/pry/code.rb', line 288 def around(line_num, lines=1) return self unless line_num select do |l, ln| ln >= line_num - lines && ln <= line_num + lines end end |
- (Code) before(line_num, lines = 1)
Remove all lines except for the lines up to and excluding line_num.
274 275 276 277 278 279 280 |
# File 'lib/pry/code.rb', line 274 def before(line_num, lines=1) return self unless line_num select do |l, ln| ln >= line_num - lines && ln < line_num end end |
- (Code) between(start_line, end_line = nil)
Remove all lines that aren't in the given range, expressed either as a
Range object or a first and last line number (inclusive). Negative
indices count from the end of the array of lines.
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/pry/code.rb', line 223 def between(start_line, end_line=nil) return self unless start_line if start_line.is_a? Range end_line = start_line.last end_line -= 1 if start_line.exclude_end? start_line = start_line.first else end_line ||= start_line end if start_line > 0 start_idx = @lines.index { |l| l.last >= start_line } || @lines.length else start_idx = start_line end if end_line > 0 end_idx = (@lines.index { |l| l.last > end_line } || 0) - 1 else end_idx = end_line end alter do @lines = @lines[start_idx..end_idx] || [] end end |
- (Code) grep(pattern)
Remove all lines that don't match the given pattern.
313 314 315 316 317 318 319 320 |
# File 'lib/pry/code.rb', line 313 def grep(pattern) return self unless pattern pattern = Regexp.new(pattern) select do |l, ln| l =~ pattern end end |
- (String) inspect
357 358 359 |
# File 'lib/pry/code.rb', line 357 def inspect Object.instance_method(:to_s).bind(self).call end |
- (Fixnum) length
Return the number of lines stored.
411 412 413 |
# File 'lib/pry/code.rb', line 411 def length @lines ? @lines.length : 0 end |
- (String) push(line, line_num = nil) Also known as: <<
Append the given line. line_num is one more than the last existing
line, unless specified otherwise.
199 200 201 202 203 |
# File 'lib/pry/code.rb', line 199 def push(line, line_num=nil) line_num = @lines.last.last + 1 unless line_num @lines.push([line.chomp, line_num]) line end |
- (String) raw
Return an unformatted String of the code.
404 405 406 |
# File 'lib/pry/code.rb', line 404 def raw @lines.map(&:first).join("\n") + "\n" end |
- (Code) select {|line| ... }
Filter the lines using the given block.
210 211 212 213 214 |
# File 'lib/pry/code.rb', line 210 def select(&blk) alter do @lines = @lines.select(&blk) end end |
- (Code) take_lines(start_line, num_lines)
Take num_lines from start_line, forward or backwards
257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/pry/code.rb', line 257 def take_lines(start_line, num_lines) if start_line >= 0 start_idx = @lines.index { |l| l.last >= start_line } || @lines.length else start_idx = @lines.length + start_line end alter do @lines = @lines.slice(start_idx, num_lines) end end |
- (String) to_s
Based on the configuration of the object, return a formatted String representation.
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
# File 'lib/pry/code.rb', line 365 def to_s lines = @lines.map(&:dup) if Pry.color lines.each do |l| l[0] = CodeRay.scan(l[0], @code_type).term end end if @with_line_numbers max_width = lines.last.last.to_s.length if lines.length > 0 lines.each do |l| padded_line_num = l[1].to_s.rjust(max_width) l[0] = "#{Pry::Helpers::Text.blue(padded_line_num)}: #{l[0]}" end end if @with_marker lines.each do |l| if l[1] == @marker_line_num l[0] = " => #{l[0]}" else l[0] = " #{l[0]}" end end end if @with_indentation lines.each do |l| l[0] = "#{' ' * @indentation_num}#{l[0]}" end end lines.map { |l| "#{l.first}\n" }.join end |
- (Code) with_indentation(spaces = 0)
Format output with the specified number of spaces in front of every line,
unless spaces is falsy.
349 350 351 352 353 354 |
# File 'lib/pry/code.rb', line 349 def with_indentation(spaces=0) alter do @with_indentation = !!spaces @indentation_num = spaces end end |
- (Code) with_line_numbers(y_n = true)
Format output with line numbers next to it, unless y_n is falsy.
326 327 328 329 330 |
# File 'lib/pry/code.rb', line 326 def with_line_numbers(y_n=true) alter do @with_line_numbers = y_n end end |
- (Code) with_marker(line_num = 1)
Format output with a marker next to the given line_num, unless line_num
is falsy.
337 338 339 340 341 342 |
# File 'lib/pry/code.rb', line 337 def with_marker(line_num=1) alter do @with_marker = !!line_num @marker_line_num = line_num end end |