lib/irb.rb in irb-1.9.1 vs lib/irb.rb in irb-1.10.0

- old
+ new

@@ -18,10 +18,11 @@ require_relative "irb/color" require_relative "irb/version" require_relative "irb/easter-egg" require_relative "irb/debug" +require_relative "irb/pager" # IRB stands for "interactive Ruby" and is a tool to interactively execute Ruby # expressions read from the standard input. # # The +irb+ command from your shell will start the interpreter. @@ -695,57 +696,61 @@ end while nil dst end def handle_exception(exc) - if exc.backtrace && exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ && + if exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ && !(SyntaxError === exc) && !(EncodingError === exc) # The backtrace of invalid encoding hash (ex. {"\xAE": 1}) raises EncodingError without lineno. irb_bug = true else irb_bug = false end - if exc.backtrace - order = nil - if RUBY_VERSION < '3.0.0' - if STDOUT.tty? - message = exc.full_message(order: :bottom) - order = :bottom - else - message = exc.full_message(order: :top) - order = :top - end - else # '3.0.0' <= RUBY_VERSION + if RUBY_VERSION < '3.0.0' + if STDOUT.tty? + message = exc.full_message(order: :bottom) + order = :bottom + else message = exc.full_message(order: :top) order = :top end - message = convert_invalid_byte_sequence(message, exc.message.encoding) - message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) unless message.encoding.to_s.casecmp?(IRB.conf[:LC_MESSAGES].encoding.to_s) - message = message.gsub(/((?:^\t.+$\n)+)/) { |m| - case order - when :top - lines = m.split("\n") - when :bottom - lines = m.split("\n").reverse + else # '3.0.0' <= RUBY_VERSION + message = exc.full_message(order: :top) + order = :top + end + message = convert_invalid_byte_sequence(message, exc.message.encoding) + message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) unless message.encoding.to_s.casecmp?(IRB.conf[:LC_MESSAGES].encoding.to_s) + message = message.gsub(/((?:^\t.+$\n)+)/) { |m| + case order + when :top + lines = m.split("\n") + when :bottom + lines = m.split("\n").reverse + end + unless irb_bug + lines = lines.map { |l| @context.workspace.filter_backtrace(l) }.compact + if lines.size > @context.back_trace_limit + omit = lines.size - @context.back_trace_limit + lines = lines[0..(@context.back_trace_limit - 1)] + lines << "\t... %d levels..." % omit end - unless irb_bug - lines = lines.map { |l| @context.workspace.filter_backtrace(l) }.compact - if lines.size > @context.back_trace_limit - omit = lines.size - @context.back_trace_limit - lines = lines[0..(@context.back_trace_limit - 1)] - lines << "\t... %d levels..." % omit - end - end - lines = lines.reverse if order == :bottom - lines.map{ |l| l + "\n" }.join - } - # The "<top (required)>" in "(irb)" may be the top level of IRB so imitate the main object. - message = message.gsub(/\(irb\):(?<num>\d+):in `<(?<frame>top \(required\))>'/) { "(irb):#{$~[:num]}:in `<main>'" } - puts message + end + lines = lines.reverse if order == :bottom + lines.map{ |l| l + "\n" }.join + } + # The "<top (required)>" in "(irb)" may be the top level of IRB so imitate the main object. + message = message.gsub(/\(irb\):(?<num>\d+):in `<(?<frame>top \(required\))>'/) { "(irb):#{$~[:num]}:in `<main>'" } + puts message + puts 'Maybe IRB bug!' if irb_bug + rescue Exception => handler_exc + begin + puts exc.inspect + puts "backtraces are hidden because #{handler_exc} was raised when processing them" + rescue Exception + puts 'Uninspectable exception occurred' end - print "Maybe IRB bug!\n" if irb_bug end # Evaluates the given block using the given +path+ as the Context#irb_path # and +name+ as the Context#irb_name. # @@ -853,15 +858,16 @@ str = "%s..." % lines.first str += "\e[0m" if Color.colorable? end end end + if multiline_p && @context.newline_before_multiline_output? - printf @context.return_format, "\n#{str}" - else - printf @context.return_format, str + str = "\n" + str end + + Pager.page_content(format(@context.return_format, str), retain_content: true) end # Outputs the local variables to this current session, including # #signal_status and #context, using IRB::Locale. def inspect @@ -924,12 +930,14 @@ format.gsub(/%([0-9]+)?([a-zA-Z])/) do case $2 when "N" @context.irb_name when "m" - truncate_prompt_main(@context.main.to_s) + main_str = @context.main.to_s rescue "!#{$!.class}" + truncate_prompt_main(main_str) when "M" - truncate_prompt_main(@context.main.inspect) + main_str = @context.main.inspect rescue "!#{$!.class}" + truncate_prompt_main(main_str) when "l" ltype when "i" if indent < 0 if $1