メタプログラミングRubyを読んでの感想的ななにか

どうも、メタプログラミング = かっこいいと思っているナサです。

最近先輩に「メタプロRubyはいい本だよ!」と言われ読み始めました。

普段からRubyを使っているのですが、Rubyの魅力や強力さを知らずに使っていたのだと思い知りました。 そこのあなた。慢心注意ですよ。

ここでは、メタプロRubyに関する感想やメモを書き連ねていきます これは超私的メモ(人にわかるように書くつもりのない)文章ですので読む価値はありませんよ〜。 ナサさんにとっては価値絶大ですが。

2章: オブジェクトモデル

1章なんてなかったんや、、、

オープンクラス

はい。よく聞く言葉ですがイマイチ意味がわかっていませんでした。 Rustでいうとstr型に自前トレイトを実装する感じでしょうか?

既存のクラスを再オープンして修正、追加を行うことをオープンクラスといいます。 オープンクラスとは言わないか、オープンクラスを使うといいます。

Arrayクラスにhoge無いんか!必須だろ!みたいな馬鹿な考えが浮かんだらこのように実装すればいいわけですね。

class Array 
  def hoge
      p 'hogehoge'
  end
end

「ひゅー。便利!!」 ライブラリでやられている方法ですね。 知らないうちにいろんなメソッドが生えたりしていますね。 そう、知らないうちに、、、

これがオープンクラスの欠点でもありますね。

そう、名前衝突! もし、もとからArrayクラスにhogeメソッドが合ったとしたら(hogehogeを出力するダサいメソッドじゃなく歴代大統領をのリストを返すような超クールなやつがあるとして)そのメソッドをhogehogeを出力する、クソみたいなやつで上書きしてしまうことになる。

これがオープンクラスの怖みですね。

クラスへの安易なパッチ追加に否定的な人たちはこのようなコードを「モンキーパッチ」という蔑称で読んでるらしい。

まあ、慎重にやろうやということで、、、

メソッド呼び出し

いい感じの画像が合ったので拝借! 拝借元書いたら大丈夫なはず(知らんけど)

赤いやつがmoduleですね。 moduleをインクルードするとRubyはモジュールを継承チェーンに入れます。 でメソッド呼び出し時に下から上へメソッド探索されていきます。

http://gpsoft.dip.jp/graphic/ruby/classd4.png

拝借元: GPソフト Wiki - Rubyのクラスモデル

3章: メソッド

動的ディスパッチ

コード実行時に呼び出すメソッドを決めることを動的ディスパッチといいます。

Rubyではsendメソッドを使うと簡単にできます。(例として悪いけど許して)

object.send(:hoge) # => hogehoge

h = :hoge
object.send(h) # => hogehoge

メタプロRubyを読むまではsendはプライベートメソッド呼び出し用だと思ってましたが、言われてみればこういった使い方もできますね。 こっちがメインなんでしょうが

動的メソッド定義

define_methodを使えば似たようなメソッドを書きまくるのを回避できます。

class Hoge 
  def self.def_print(name)
    define_method(name) do 
      p name
    end
  end

  def_print :hoge
  def_print :fugu
  def_print :guga
end

ゴーストメソッド

Rubyはメソッドが見つからない場合method_missingを呼び出す。

これを利用してmethod_missingをオーバーライドすることで、存在しないメソッドを呼び出すことが出来る。

ゴーストメソッドと実際のメソッド名が衝突すると、実際のやつが呼び出されるのでゴーストメソッドを使うときは注意