昨日の記事 に babieさんが反応 してくださったけれど、
[64, 65, 66].map(&(:succ * :chr * :to_sym)) って前から作用するのかぁ、* だと順番がよくイメージできないなぁ。そんなもん?
うわあぁぁぁ。方向を間違えて実装した件。合成をそうやって定義する流儀もあるけど、マイナーだよね。少なくとも、私の意図や『圏論の基礎』とは違う。なぜサンプルを書いてる時点で気づかなかったんだろう。穴があったら入りたい。
実装(改)
Procを混ぜられるようにも意図してたんだけれど、Procが左辺の場合を忘れていたのでそれも含めて修正。
class Symbol unless instance_methods.include?("to_proc") def to_proc Proc.new{|obj, *args| obj.__send__(self, *args)} end end def * rhs MethodComposition.new([rhs.to_proc, self.to_proc]) end def ** num MethodComposition.new(Array.new(num, self.to_proc)) end end class Proc def * rhs MethodComposition.new([rhs.to_proc, self]) end def ** num MethodComposition.new(Array.new(num, self)) end end class MethodComposition def initialize(elements = []) @chain = elements end def * rhs MethodComposition.new(@chain.dup.unshift(rhs.to_proc)) end def ** num MethodComposition.new(@chain * num) end def to_proc Proc.new{|receiver| @chain.inject(receiver) {|obj, proc| proc.call(obj) } } end end class Object def callcomp(proc = nil) unless proc self else proc.to_proc.call self end end end
実行例
(0...3).map(&(:to_sym * :chr * :succ**64)) # => [:A, :B, :C]
無意味に結合律を試してみたり。
(0...3).map &((:intern * :succ) * (:chr * :succ**32) * :succ**32) # => [:A, :B, :C]
lambdaを混ぜてみたり
(0...3).map &(lambda{|x| "#{x}#{x.length}"}**3 * :chr * :succ**65) # => ["A123", "B123", "C123"]
便利だか便利でないんだか分からなかったり
"".callcomp(:inspect ** 3) # => "\"\\\"\\\\\\\"\\\\\\\"\\\"\""
遊んでみたり
(0..4).map &( :inspect * ObjectSpace::method(:_id2ref)) # => ["false", "0", "true", "1", "nil"] (0..4).map &( lambda{|x| class<<x; self; end}**2 * :class * ObjectSpace::method(:_id2ref) ) # => [#<Class:#<Class:FalseClass>>, #<Class:#<Class:Fixnum>>, #<Class:#<Class:TrueClass>>, #<Class:#<Class:Fixnum>>, #<Class:#<Class:NilClass>>]
もう、無茶苦茶
(-4..0).map &( :succ**((?z-?s)*(1+26)) * (:to_s * lambda{|x| class<<x; self; end} * :class) * ObjectSpace::method(:_id2ref) * :-@) # => ["#<Class:NilClazz>", "#<Class:Fixobt>", "#<Class:TrueClazz>", "#<Class:Fixobt>", "#<Class:FalseClazz>"]