Rubyリファレンス: Home

class_eval, module_eval (Module)

Edit   History

標準クラス・モジュール > Module > class_eval, module_eval

mod.class_eval { block }
mod.module_eval { block }

class_evalメソッドは、ブロックをクラス定義やモジュール定義の中のコードであるように実行します。ブロックの戻り値がメソッドの戻り値になります。

module_evalメソッドはclass_evalの別名です。Classオブジェクトに対してmodule_evalを呼び出せますし、Moduleオブジェクトに対してclass_evalを呼び出せます。

ブロック内でのselfClassオブジェクトやModuleオブジェクトを指します。ブロックの外側のローカル変数はブロック内でも使えます。

class_evalmodule_evalを使うと、クラスやモジュールの外側でインスタンスメソッドを定義したり、Moduleクラスのprivateメソッドを呼び出したりできます。次の例では、attr_accessorメソッドでvar1var10という属性を作成しています。変数iclass_evalのブロックの中で使えます。

class Product
end
 
1.upto(10) do |i|
  Product.class_eval { attr_accessor :"var#{i}" }
end
product = Product.new
product.var4 = "Cool"
puts product.var4
Cool

Ruby 1.9 Ruby 1.8ではブロック引数を指定すると、ClassオブジェクトやModuleオブジェクトを取り出せますが、Ruby 1.9ではブロック引数はなくなりました。代わりにselfを使います。

String.class_eval {|klass| p klass }
String   (Ruby 1.8の場合)
mod.class_eval(code [, filename [, lineno]])
mod.module_eval(code [, filename [, lineno]])

class_evalメソッドの引数に文字列codeを渡すと、その文字列をクラス定義やモジュール定義の中のコードであるように実行します。戻り値は、文字列のコードの戻り値です。

次の例は、class_evalを使ってメソッドdowncaseupcaseを定義します。文字列のコードの中では、#{ ~ }で変数の値を埋め込めます。

class User
  attr_accessor :name
  def initialize(name)
    @name = name
  end
  
  [:downcase, :upcase].each do |method|
    class_eval <<-EOS
      def #{method}
        @name.#{method}
      end
    EOS
  end
end
 
user = User.new("taro")
puts user.upcase
TARO

第2引数と第3引数には例外のバックトレース情報を指定できます。第2引数filenameにはファイル名を、第3引数linenoには行番号を指定します。

User.class_eval("invalid", "class_eval", 999)
class_eval:999: undefined local variable or method `invalid' for User:Class (Nam
eError)

関連項目