Discussion:
Capture calls to `eval`.
Samuel Williams
2018-07-01 00:32:37 UTC
Permalink
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
Greg Navis
2018-07-09 18:50:18 UTC
Permalink
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')
Ryan Davis
2018-07-09 19:52:32 UTC
Permalink
Post by Samuel Williams
@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-***@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>
Samuel Williams
2018-08-13 00:39:35 UTC
Permalink
I tried both those methods and the only one that worked was monkey patching
Kernel.
Post by Ryan Davis
Post by Samuel Williams
@call_trace = TracePoint.new(:c_call) do |trace_point|
if trace_point.method_id == :eval
# How to get args?
end
end
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
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>
Loading...