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 44 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 28 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 12 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 36 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 52 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 89 def allowing_other_threads Byebug.unlock res = yield Byebug.lock res end
# File lib/byebug/helpers/eval.rb, line 70 def error_msg(e) at = e.backtrace locations = ["#{at.shift}: #{warning_msg(e)}"] 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 thred's result.
# File lib/byebug/helpers/eval.rb, line 103 def in_new_thread res = nil Thread.new { res = yield }.join res end
# File lib/byebug/helpers/eval.rb, line 64 def msg(e) msg = Setting[:stack_on_error] ? error_msg(e) : warning_msg(e) pr('eval.exception', text_message: msg) end
# File lib/byebug/helpers/eval.rb, line 58 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 111 def safe_inspect(var) var.inspect rescue safe_to_s(var) end
# File lib/byebug/helpers/eval.rb, line 117 def safe_to_s(var) var.to_s rescue '*Error in evaluation*' end
# File lib/byebug/helpers/eval.rb, line 78 def warning_msg(e) "#{e.class} Exception: #{e.message}" end