LoginSignup
6
7

More than 5 years have passed since last update.

Rubyで呼び出し元での変数名を取得する

Posted at

TracePointを使う

def greet(greetings, time)
  unless greetings.key?(time)
    raise "[ERROR] #{time} is not in #{$var}"
  end

  puts greetings[time]
end

TracePoint.trace(:line) do |tp|
  $b = tp.binding
end

TracePoint.trace(:call) do |tp|
  return unless tp.method_id == :greet
  greetings = tp.binding.local_variable_get(:greetings)
  $var = $b.local_variables.detect {|v| $b.local_variable_get(v) == greetings }
end

english_greetings = {
  morning: 'Good morning!'
}

greet(english_greetings, :night)

binding_of_callerを使う

require 'binding_of_caller'

def greet(greetings, time)
  unless greetings.key?(time)
    b = binding.of_caller(1)
    var = b.local_variables.detect {|v| b.local_variable_get(v) == greetings }
    raise "[ERROR] #{time} is not in #{var}"
  end

  puts greetings[time]
end

english_greetings = {
  morning: 'Good morning!'
}

greet(english_greetings, :night)

binding_ninjaを使う

require 'binding_ninja'

self.class.extend BindingNinja

def greet(b, greetings, time)
  unless greetings.key?(time)
    var = b.local_variables.detect {|v| b.local_variable_get(v) == greetings }
    raise "[ERROR] #{time} is not in #{var}"
  end

  puts greetings[time]
end

self.class.class_eval { auto_inject_binding :greet }

english_greetings = {
  morning: 'Good morning!'
}

greet(english_greetings, :night)
6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7