Module: InstanceVariableTracer
- Defined in:
- lib/instance_variable_tracer.rb,
lib/instance_variable_tracer/version.rb
Constant Summary collapse
- VERSION =
"0.1.0"
Class Method Summary collapse
-
.start(target_instance_variable_name:, target_class_name: nil) ⇒ Object
usage: InstanceVariableTracer.start(target_instance_variable_name: “@books”).
Class Method Details
.start(target_instance_variable_name:, target_class_name: nil) ⇒ Object
usage: InstanceVariableTracer.start(target_instance_variable_name: “@books”)
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/instance_variable_tracer.rb', line 5 def self.start(target_instance_variable_name:, target_class_name: nil) TracePoint.trace(:line) do |tp| # TracePointで止めてASTを確認し、インスタンス変数への代入かどうかを調べる # puts "[TP:#{tp.event}] #{tp.path}:#{tp.lineno} #{tp.method_id} #{tp.defined_class}" begin line = File.open(tp.path, "r"){|f| f.readlines[tp.lineno - 1] } # TODO: ファイルがないクラスでは使えない rescue Errno::ENOENT => e # p "File.open error" # p tp # p tp.path end next unless line # AST取得 begin node = RubyVM::AbstractSyntaxTree.parse(line).children.last rescue Exception => e # 乱暴 next end # インスタンス変数への代入かを調べる next unless node.type == :IASGN # クラス名を調べる if target_class_name target_class = Kernel.const_get(target_class_name) next unless tp.self.is_a?(target_class) end # インスタンス変数名を調べる instance_variable_name = node.children.first next unless instance_variable_name == target_instance_variable_name.to_sym puts "#{target_class_name} #{target_instance_variable_name} is assigned in #{tp.path}:#{tp.lineno} #{tp.method_id} #{tp.defined_class}" end end |