Class: Pry::Code
- Extended by:
- MethodSource::CodeHelpers
- Defined in:
- lib/pry/code.rb
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
-
#code_type ⇒ Symbol
The type of code stored in this wrapper.
Class Method Summary collapse
-
.from_file(fn, code_type = nil) ⇒ Code
Instantiate a
Codeobject containing code loaded from a file or Pry's line buffer. -
.from_method(meth, start_line = nil) ⇒ Code
Instantiate a
Codeobject containing code extracted from a::Method,UnboundMethod,Proc, orPry::Methodobject. -
.from_module(mod, start_line = nil, candidate_rank = 0) ⇒ Code
Attempt to extract the source code for module (or class)
mod.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Two
Codeobjects are equal if they contain the same lines with the same numbers. -
#after(line_num, lines = 1) ⇒ Code
Remove all lines except for the
linesafter and excludingline_num. -
#around(line_num, lines = 1) ⇒ Code
Remove all lines except for the
lineson either side of and includingline_num. -
#before(line_num, lines = 1) ⇒ Code
Remove all lines except for the
linesup to and excludingline_num. -
#between(start_line, end_line = nil) ⇒ Code
Remove all lines that aren't in the given range, expressed either as a
Rangeobject or a first and last line number (inclusive). -
#comment_describing(line_number) ⇒ String
Get the comment that describes the expression on the given line number.
-
#expression_at(line_number, consume = 0) ⇒ String
Get the multiline expression that starts on the given line number.
-
#grep(pattern) ⇒ Code
Remove all lines that don't match the given
pattern. -
#initialize(lines = [], start_line = 1, code_type = :ruby) ⇒ Code
constructor
Instantiate a
Codeobject containing code from the givenArray,String, orIO. - #inspect ⇒ String
-
#length ⇒ Fixnum
Return the number of lines stored.
-
#method_missing(name, *args, &blk) ⇒ Object
Forward any missing methods to the output of
#to_s. -
#push(line, line_num = nil) ⇒ String
(also: #<<)
Append the given line.
-
#raw ⇒ String
Return an unformatted String of the code.
-
#select {|line| ... } ⇒ Code
Filter the lines using the given block.
-
#take_lines(start_line, num_lines) ⇒ Code
Take
num_linesfromstart_line, forward or backwards. -
#to_s ⇒ String
Based on the configuration of the object, return a formatted String representation.
-
#with_indentation(spaces = 0) ⇒ Code
Format output with the specified number of spaces in front of every line, unless
spacesis falsy. -
#with_line_numbers(y_n = true) ⇒ Code
Format output with line numbers next to it, unless
y_nis falsy. -
#with_marker(line_num = 1) ⇒ Code
Format output with a marker next to the given
line_num, unlessline_numis falsy.
Constructor Details
#initialize(lines = [], start_line = 1, code_type = :ruby) ⇒ Code
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.
126 127 128 129 130 131 132 133 |
# File 'lib/pry/code.rb', line 126 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
#method_missing(name, *args, &blk) ⇒ Object
Forward any missing methods to the output of #to_s.
390 391 392 |
# File 'lib/pry/code.rb', line 390 def method_missing(name, *args, &blk) to_s.send(name, *args, &blk) end |
Instance Attribute Details
#code_type ⇒ Symbol
Returns The type of code stored in this wrapper.
116 117 118 |
# File 'lib/pry/code.rb', line 116 def code_type @code_type end |
Class Method Details
.from_file(fn, code_type = nil) ⇒ Code
Instantiate a Code object containing code loaded from a file or
Pry's line buffer.
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/pry/code.rb', line 38 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 MethodSource::SourceNotFoundError, "Cannot open #{fn.inspect} for reading." end end new(f, 1, code_type || :ruby) ensure f.close if f.respond_to?(:close) end |
.from_method(meth, start_line = nil) ⇒ Code
Instantiate a Code object containing code extracted from a
::Method, UnboundMethod, Proc, or Pry::Method object.
62 63 64 65 66 |
# File 'lib/pry/code.rb', line 62 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 |
.from_module(mod, start_line = nil, candidate_rank = 0) ⇒ Code
Attempt to extract the source code for module (or class) mod.
76 77 78 79 80 81 |
# File 'lib/pry/code.rb', line 76 def from_module(mod, start_line=nil, candidate_rank=0) candidate = Pry::WrappedModule(mod).candidate(candidate_rank) start_line ||= candidate.line new(candidate.source, start_line, :ruby) end |
Instance Method Details
#==(other) ⇒ Boolean
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.
378 379 380 381 382 383 384 385 386 387 |
# File 'lib/pry/code.rb', line 378 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 |
#after(line_num, lines = 1) ⇒ Code
Remove all lines except for the lines after and excluding line_num.
243 244 245 246 247 248 249 |
# File 'lib/pry/code.rb', line 243 def after(line_num, lines=1) return self unless line_num select do |l, ln| ln > line_num && ln <= line_num + lines end end |
#around(line_num, lines = 1) ⇒ Code
Remove all lines except for the lines on either side of and including
line_num.
230 231 232 233 234 235 236 |
# File 'lib/pry/code.rb', line 230 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 |
#before(line_num, lines = 1) ⇒ Code
Remove all lines except for the lines up to and excluding line_num.
216 217 218 219 220 221 222 |
# File 'lib/pry/code.rb', line 216 def before(line_num, lines=1) return self unless line_num select do |l, ln| ln >= line_num - lines && ln < line_num end end |
#between(start_line, end_line = nil) ⇒ Code
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.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/pry/code.rb', line 165 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 |
#comment_describing(line_number) ⇒ String
Get the comment that describes the expression on the given line number.
347 348 349 |
# File 'lib/pry/code.rb', line 347 def comment_describing(line_number) self.class.comment_describing(raw, line_number) end |
#expression_at(line_number, consume = 0) ⇒ String
Get the multiline expression that starts on the given line number.
355 356 357 |
# File 'lib/pry/code.rb', line 355 def expression_at(line_number, consume=0) self.class.expression_at(raw, line_number, :consume => consume) end |
#grep(pattern) ⇒ Code
Remove all lines that don't match the given pattern.
255 256 257 258 259 260 261 262 |
# File 'lib/pry/code.rb', line 255 def grep(pattern) return self unless pattern pattern = Regexp.new(pattern) select do |l, ln| l =~ pattern end end |
#inspect ⇒ String
299 300 301 |
# File 'lib/pry/code.rb', line 299 def inspect Object.instance_method(:to_s).bind(self).call end |
#length ⇒ Fixnum
Return the number of lines stored.
369 370 371 |
# File 'lib/pry/code.rb', line 369 def length @lines ? @lines.length : 0 end |
#push(line, line_num = nil) ⇒ String Also known as: <<
Append the given line. line_num is one more than the last existing
line, unless specified otherwise.
141 142 143 144 145 |
# File 'lib/pry/code.rb', line 141 def push(line, line_num=nil) line_num = @lines.last.last + 1 unless line_num @lines.push([line.chomp, line_num]) line end |
#raw ⇒ String
Return an unformatted String of the code.
362 363 364 |
# File 'lib/pry/code.rb', line 362 def raw @lines.map(&:first).join("\n") + "\n" end |
#select {|line| ... } ⇒ Code
Filter the lines using the given block.
152 153 154 155 156 |
# File 'lib/pry/code.rb', line 152 def select(&blk) alter do @lines = @lines.select(&blk) end end |
#take_lines(start_line, num_lines) ⇒ Code
Take num_lines from start_line, forward or backwards
199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/pry/code.rb', line 199 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 |
#to_s ⇒ String
Based on the configuration of the object, return a formatted String representation.
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/pry/code.rb', line 307 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::BaseHelpers.colorize_code(padded_line_num.to_s)}: #{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 |
#with_indentation(spaces = 0) ⇒ Code
Format output with the specified number of spaces in front of every line,
unless spaces is falsy.
291 292 293 294 295 296 |
# File 'lib/pry/code.rb', line 291 def with_indentation(spaces=0) alter do @with_indentation = !!spaces @indentation_num = spaces end end |
#with_line_numbers(y_n = true) ⇒ Code
Format output with line numbers next to it, unless y_n is falsy.
268 269 270 271 272 |
# File 'lib/pry/code.rb', line 268 def with_line_numbers(y_n=true) alter do @with_line_numbers = y_n end end |
#with_marker(line_num = 1) ⇒ Code
Format output with a marker next to the given line_num, unless line_num
is falsy.
279 280 281 282 283 284 |
# File 'lib/pry/code.rb', line 279 def with_marker(line_num=1) alter do @with_marker = !!line_num @marker_line_num = line_num end end |