昨日の記事に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>"]
コメント