class_eval(code, file, lineno)
eval.rb
class Shino
def self.shino
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def name
puts 'fumi'
raise
end
RUBY
end
end
Shino.shino
s = Shino.new
s.name
# => fumi
# eval.rb:6:in `name': unhandled exception
# from eval.rb:14:in `<main>'
#
# shell returned 1
第1引数に渡された文字列は、クラス定義の中のコードであるように実行される。上記の例だとShinoクラスのインスタンスメソッドnameが定義される。
第2引数と第3引数はstacktraceのときに利用される。
第2引数に__FILE__
、第3引数に__LINE__ + 1
としておくとわかりやすい。
参考)
利用例)
ActiveSupport::Callbacks::ClassMethods#define_callbacksで利用されている。
activesupport/lib/active_support/callbacks.rb
module ActiveSupport
module Callbacks
module ClassMethods
def define_callbacks(*names)
options = names.extract_options!
names.each do |name|
class_attribute "_#{name}_callbacks"
set_callbacks name, CallbackChain.new(name, options)
module_eval <<-RUBY, __FILE__, __LINE__ + 1
def _run_#{name}_callbacks(&block)
_run_callbacks(_#{name}_callbacks, &block)
end
RUBY
end
end
end
end
end