I would like to capture calls to eval.
I tried using trace points which does get pretty close:
@call_trace = TracePoint.new(:c_call) do |trace_point|
if trace_point.method_id == :eval
# How to get args?
end
end
I also tried to override Kernel.eval but that didn't seem to work correctly
either. I might be doing something wrong.
Any ideas or suggestions would be greatly appreciated.
Kind regards,
Samuel
I looked at the docs and it seems there's no easy way to get the argument.
I recommend you try to patch Kernel like this:
module Kernel
alias_method :original_eval, :eval
def eval(*args)
p args
original_eval(*args)
end
end
# This prints:
···
#
# ["1 + 3"] (#p in Kernel.eval)
# 4 (the actual result)
puts eval('1 + 3')
via the binding:
TRACE_FMT = "%s:%d %s#%s %p"
@call_trace = TracePoint.new(:c_call) do |tp|
next unless tp.method_id == :eval
args = tp.binding.local_variables.map { |v|
[v, tp.binding.local_variable_get(v)]
}.to_h
puts TRACE_FMT % [tp.path, tp.lineno, tp.defined_class, tp.method_id, args]
end
···
On Jun 30, 2018, at 17:32, Samuel Williams <space.ship.traveller@gmail.com> wrote:
@call_trace = TracePoint.new(:c_call) do |trace_point|
if trace_point.method_id == :eval
# How to get args?
end
end
I tried both those methods and the only one that worked was monkey patching
Kernel.
···
On 10 July 2018 at 04:52, Ryan Davis <ryand-ruby@zenspider.com> wrote:
> On Jun 30, 2018, at 17:32, Samuel Williams <space.ship.traveller@gmail. > > wrote:
>
> @call_trace = TracePoint.new(:c_call) do |trace_point|
> if trace_point.method_id == :eval
> # How to get args?
> end
> end
via the binding:
TRACE_FMT = "%s:%d %s#%s %p"
@call_trace = TracePoint.new(:c_call) do |tp|
next unless tp.method_id == :eval
args = tp.binding.local_variables.map { |v|
[v, tp.binding.local_variable_get(v)]
}.to_h
puts TRACE_FMT % [tp.path, tp.lineno, tp.defined_class, tp.method_id,
args]
end
Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>