カテゴリー:
Rails
タグ:
 class_eval define_method メタプログラミング フラットスコープ

このエントリーをはてなブックマークに追加
更新日時:
2013年08月29日(木)
作成日時:
2013年08月29日(木)

前の記事 / 次の記事

参考:外側のスコープを参照しつつ特異メソッドを書く

特異メソッド

article = Article.new

article.respond_to? :add_signature
#=> false

def article.add_signature
  content << "Written by Ore"
end

article.respond_to? :add_signature
#=> true

特異メソッドをフラットスコープで書く場合(外部の値を持ち込みたい場合)、
次のようには書けない

article = Article.new
signature = "Written by Ore"

article.respond_to? :add_signature
#=> false

define_method article.add_signature do
  content << signature
end

article.respond_to? :add_signature
#=> false

特異メソッドをフラットスコープで書く場合(外部の値を持ち込みたい場合)、
次のように書ける

article = Article.new
signature = "Written by Ore"

article.respond_to? :add_signature
#=> false

article.class_eval do
  define_method :add_signature do
   content << signature
  end
end

article.respond_to? :add_signature
#=> true

※ActiveSupportを使っていない場合は上記のようには書けないので、
次のように書く

article = Article.new
signature = "Written by Ore"

article.respond_to? :add_signature
#=> false

(class << article; self end).class_eval do
  define_method :add_signature do
   content << add_signature
  end
end

article.respond_to? :add_signature
#=> true

#
# (class << article; self end)
# は次の意味で、つまりarticleの特異クラスを手に入れている
#
class << article
  self
end