module Byebug::Helpers::EvalHelper
Utilities to assist evaluation of code strings
Public Instance Methods
Evaluates a string containing Ruby code in a specific binding, handling the errors at an error level.
# File lib/byebug/helpers/eval.rb, line 45 def error_eval(str, binding = frame._binding) safe_eval(str, binding) { |e| raise(e, msg(e)) } end
Evaluates an expression
that might use or defer execution to
threads other than the current one.
@note This is necessary because when in byebug's prompt, every thread is “frozen” so that nothing gets run. So we need to unlock threads prior to evaluation or we will run into a deadlock.
@param expression [String] Expression to evaluate
# File lib/byebug/helpers/eval.rb, line 29 def multiple_thread_eval(expression) allowing_other_threads { warning_eval(expression) } end
Evaluates an expression
in a separate thread.
@param expression [String] Expression to evaluate
# File lib/byebug/helpers/eval.rb, line 13 def separate_thread_eval(expression) allowing_other_threads do in_new_thread { warning_eval(expression) } end end
Evaluates a string containing Ruby code in a specific binding, returning nil in an error happens.
# File lib/byebug/helpers/eval.rb, line 37 def silent_eval(str, binding = frame._binding) safe_eval(str, binding) { |_e| nil } end
Evaluates a string containing Ruby code in a specific binding, handling the errors at a warning level.
# File lib/byebug/helpers/eval.rb, line 53 def warning_eval(str, binding = frame._binding) safe_eval(str, binding) { |e| errmsg(msg(e)) } end
Private Instance Methods
Run block temporarily ignoring all TracePoint events.
Used to evaluate stuff within Byebug's prompt. Otherwise, any code creating new threads won't be properly evaluated because new threads will get blocked by byebug's main thread.
# File lib/byebug/helpers/eval.rb, line 90 def allowing_other_threads Byebug.unlock res = yield Byebug.lock res end
# File lib/byebug/helpers/eval.rb, line 71 def error_msg(exception) at = exception.backtrace locations = ["#{at.shift}: #{warning_msg(exception)}"] locations += at.map { |path| " from #{path}" } locations.join("\n") end
Runs the given block in a new thread, waits for it to finish and returns the new thread's result.
# File lib/byebug/helpers/eval.rb, line 104 def in_new_thread res = nil Thread.new { res = yield }.join res end
# File lib/byebug/helpers/eval.rb, line 65 def msg(exception) msg = Setting[:stack_on_error] ? error_msg(exception) : warning_msg(exception) pr("eval.exception", text_message: msg) end
# File lib/byebug/helpers/eval.rb, line 59 def safe_eval(str, binding) binding.eval(str.gsub(/\Aeval /, ""), "(byebug)", 1) rescue StandardError, ScriptError => e yield(e) end
# File lib/byebug/helpers/eval.rb, line 112 def safe_inspect(var) var.inspect rescue StandardError safe_to_s(var) end
# File lib/byebug/helpers/eval.rb, line 118 def safe_to_s(var) var.to_s rescue StandardError "*Error in evaluation*" end
# File lib/byebug/helpers/eval.rb, line 79 def warning_msg(exception) "#{exception.class} Exception: #{exception.message}" end