undef_methodはクラスにメソッドを追加する?

Module#undef_methodを使うと、「親クラスのメソッドは子クラスで未定義にできる。子クラスで未定義にしたメソッドを孫クラスから呼ぶと未定義になる」ということに気づきました。つまり、「孫→子→親」とメソッドを探すとき、子をスルーして親のメソッドを呼ぶのではなく、子の「未定義」にぶつかるということです。

動作としては自然ですが、どうなっているのでしょう。

class Parent
  def greet() "hello" end
end
class Child < Parent
  undef_method :greet
end
class GrandChild < Child
end
 
p GrandChild.new.respond_to?(:greet) #=> false

以下はRuby 1.9.1-p376のvm_method.cの関数rb_undef。クラスklassに名前がidで内容が0のメソッドを加えています。これは「同名で呼び出せないメソッド」を新たに加えているのではないだろうか(あまり自信なし)。

476 void
477 rb_undef(VALUE klass, ID id)
478 {
(中略)
515     rb_add_method(klass, id, 0, NOEX_PUBLIC);

Module#privateも、親のメソッドを子でprivateにできます。この場合は、privateメソッドが「名前と内容が同じでprivateフラグが立ったメソッドを子に加える」ことをprivate_instance_methods(false)で確認できます。

class Parent
  def greet() "hello" end
end
class Child < Parent
  private :greet
end

p Child.private_instance_methods(false) #=> [:greet]

Module#alias_methodもまた、新しいメソッドを加えるメソッドで、「名前が別で内容が同じものを指すメソッドを加える」であると思われます。

class Parent
  def greet() "hello" end
end
class Child < Parent
  alias_method :orig_greet, :greet
end

p Child.public_instance_methods(false) #=> [:orig_greet]

元メソッドを削除・未定義・上書きしても、別名メソッドは同じ機能を保持します。これは、元メソッドの内容は消されず、別名メソッドが元メソッドの内容を指したままである、ということなのでしょう。

結論:Rubyのメソッドの内容はポインタで参照されており、参照元のメソッドを新しく作るといろいろできる(だと思う)。