Help us understand the problem. What is going on with this article?

オブジェクトのインスタンス(または特異)メソッドを取得する[ ]と、特異メソッドを設定する[ ]= をシンボルに定義してみる。(読書メモ)

More than 3 years have passed since last update.

 前記事につづき、プログラミング言語Ruby を読んでいる中で、覚えておきたいと思った、(ややトリッキーな)コードです。
 以下は、同著6.8 関数プログラミング の節の最後に出てきたものに若干手を加えたもので、Symbolクラスに[],[]= 演算子を追加して、オブジェクトの特異メソッドを取得、設定するものです。(なお、実行はruby 2.2 で試しています。)

class Symbol

  def [](o)
    o.method(self)
  end

  def []=(o,f)
    sym = self
    eigenclass = (class << o; self; end)
    eigenclass.instance_eval do
      define_method(sym, f)
    end
  end

end

こうしておいて

str = '='

puts :*[str][10]

とすると、'=' が10個連続した文字列、

==========

が表示される
次に、[]=を使って、

:*[str] = lambda {|n|
    ret = ''
    n.times {|i|
        ret += (self + (i < n-1 ? '|':''))
    }
    ret
}

としてから、再度

puts :*[str][10]

とすると、10個の'='の間に、'|'が挿入されて、

=|=|=|=|=|=|=|=|=|=

が表示される。

さらに、上記のSymbol への[]に加えて、Methodクラスに数学的な意味での関数 f,gの合成

(f・g)(x) ≡ f(g(x))

に相当するアスタリスク演算子 * を以下のように定義する。

class Method
  def *(f)
    if self.respond_to?(:arity) && self.arity  == 1
      lambda {|*args| self.call(f[*args])}
    else
      lambda {|*args| self.call(* f[*args])}
    end
  end
end

上記のSymbolとMethodを使うと

(:*[2]*:+[3])[4]

は、「3を足してから2を掛ける」という関数に 4 を渡す、すなわち

2 * (3 + 4)

と同じで、結果は 14 になる。

以上です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした