LoginSignup
7
5

More than 5 years have passed since last update.

class_evalの第1引数に文字列を渡したときの挙動についてメモ

Last updated at Posted at 2015-02-20

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
7
5
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
7
5