simanのブログ

ゆるふわプログラマー。競技プログラミングやってます。Ruby好き

Ryudai.rb第1回まとめ(2) class_eval編

前回のinstance_evalに引き続き次はclass_eval
class_evalはブロックで渡された文をまるで、classの定義の中にいるかのように実行でき
るメソッド。これもなかなかに壊れている。

class Siman
  def initialize
    @siman = "Siman"
  end
end

s = Siman.new

puts s.siman

変数@simanはaccessorを定義していないので参照を行おうとするとエラーが生じる

class_eval.rb:9:in `<main>': undefined method `siman' for #<Siman:0x007fd67585e230 @siman="Siman"> (NoMethodError)

そこでclass_evalを使ってみる

class Siman
  def initialize
    @siman = "Siman"
  end
end

s = Siman.new

Siman.class_eval{
  attr_accessor :siman
}

puts s.siman

で実行

Siman

こんな感じで、途中からでもaccessorを定義できちゃったりする。(こんな使い方はしないけど)

class Siman
  def initialize
    @siman = "Siman"
  end
end

s = Siman.new

Siman.class_eval{
  def hello
    puts "Hello World"
  end
}

s.hello
Hello World

class_evalを使えば途中でメソッドの定義とかもできちゃう。メソッドの定義ならdefine_methodでやれって感じもするけど今回はスルーしておきます。


まとめ
class_evalを使えば、ブロック文に渡したコードをクラスの定義内で実行できる