# -*- ruby -*- # recursive iterator and recursive block class Object CALL_STACK__ = [] def save_call(sym, *args, &block) CALL_STACK__.push([sym,args,block]) begin resp = __send__(sym,*args,&block) ensure CALL_STACK__.pop end return resp end def save_block(sym, rsyms, *args, &block) obj = __send__(sym,*args,&block) rsyms.each{|rsym| obj.instance_eval [ "alias _#{rsym}_ #{rsym}", "def #{rsym}(*args)", " CALL_STACK__.push([nil,nil,self])", " begin", " resp = _#{rsym}_(*args)", " ensure", " CALL_STACK__.pop", " end", " resp", "end", ].join("\n") } obj end def restore_block() CALL_STACK__[-1][2] end def restore_call() __send__(CALL_STACK__[-1][0], *(CALL_STACK__[-1][1]), &(CALL_STACK__[-1][2])) end alias recursive save_call alias recurse restore_call def y_comb(sym,*args,&block) u = proc{|f| f[f]} u1 = proc{|f| __send__(sym,*args){|*x| yield(f[f]).call(*x)}} u[u1] end alias pass_block y_comb end if( __FILE__ == $0 ) ary = [1,2,[31,32],[41,42,[431,432]]] print("recursive --\n") ary.recursive(:each){|elem| case elem when Array elem.recurse else p elem end } print("fact --\n") fact = Proc.y_comb(:new){|cb| proc{|n| if( n > 1 ) n * cb.call(n-1) else n end }} p fact.call(3) print("sum --\n") sum = Proc.y_comb(:new){|cb| proc{|n| if( n > 0 ) n + cb.call(n-1) else n end }} p sum.call(10) end