maeshimaの日記

メモ書きです

メタプログラミングRubyのイディオム

メタプログラミングRubyでは、説明しやすくするために、各テクニックにそれぞれ名前を付けている。最初覚えるのは面倒だけど、覚えるとこれは必要な儀式だったんだなと思える。というわけでメモ。

動的ディスパッチ

sendを使って動的にメソッドを利用すること。

動的メソッド

define_methodを使って動的にメソッドを定義すること

ゴーストメソッド

method_missing を使ってできた、実際には存在しないメソッドのこと。

動的プロキシ

オブジェクトがゴーストメソッドを受け取り、なんらかのロジックを適用してから、他のオブジェクトに転送すること

ミミックメソッド

実際はメソッドだけどキーワードっぽく使われるものをミミックメソッドと呼ぶ。

puts "hoge" # キーワードっぽく見えるけどメソッド
obj.my_attributes = "hoge" # 属性っぽく見えるけどメソッド

nilガード

こういうやつ

a ||= []

名前付き引数

hashで渡す引数のこと

def my_method(args)
  args
end
my_method(:a => "x", :b => 3, :c => "y")

配列引数

def my_method(*args)
  args

自己yield

selfをブロック引数に渡してyieldすること。こんな感じで実装しておくと

module Gem
  class Specification
    def initialize
    yield self if block_given?
    # ...

こんな風にかけて便利

spec = Gem::Specification.new do |s|
  s.name = "My Gem name"
  s.version = "0.0.1"
  # ...
end

スコープゲート

スコープが切り替わる場所

  • class
  • module
  • def

フラットスコープ

スコープゲートをブロックに置き換える(classをClass.new {}, defをdefine_method {})ことで、他のスコープの変数を見られるようにするテクニックのこと。

共有スコープ

フラットスコープで共有変数を使うときに、他から参照できないようにスコープゲートで区切ってつくるスコープのこと。

コンテキスト探査機

instance_eval に渡したブロックのこと

クリーンルーム

ブロックを評価するときに、環境を汚さないためのオブジェクトを新しく作り、instance_evalを使ってその中でブロックを評価する。その際のオブジェクトのこと。

クリーンルームなしでブロック中でインスタンス変数を操作していたりすると、思っていないバグの温床になる。