From: Brian Adkins Date: 2007-10-06T02:30:04+09:00 Subject: Re: (Newbie) Override * on Array On Oct 4, 7:04 am, Stefano Crocco wrote: > require 'generator' > > class Array > > def *(other) > SyncEnumerator.new(self, other).map{|x, y| x*y} > end > > end Thanks for the tip on SyncEnumerator. If a class/module must be opened, I think Enumerator would be better than Array. Also, I prefer method names over operators in this case, but that's a personal preference: require 'generator' require 'pp' module Enumerable def cartesian_product other self.inject([]) {|result, a| other.each {|b| result << [a, b] }; result } end def dot_product other SyncEnumerator.new(self, other).inject(0) {|s,v| s += v[0]*v[1]; s } end def mmap *others, &f SyncEnumerator.new(self, *others).map(&f) end def cross_product other # exercise for reader end end x = [1, 2, 3] y = [1, 10, 100] pp x.dot_product(y) puts '-'*10 pp x.mmap(y) {|a,b| a*b } pp x.mmap(y, [1, 2, 4]) {|a,b,c| a*b*c } puts '-'*10 pp x.cartesian_product(y) puts '-'*10 BTW, with the mmap call above, I originally got bit by a scope issue because I named the local variables |x,y|, so the assignment to the block variables overwrote x & y in the outer scope :( Personally, I'd prefer to not open a class/module and simply define functions. def cartesian_product enum1, enum2 enum1.inject([]) {|result, a| enum2.each {|b| result << [a, b] }; result } end def dot_product enum1, enum2 SyncEnumerator.new(enum1, enum2).inject(0) {|s,v| s += v[0]*v[1]; s } end def mmap *enums, &f SyncEnumerator.new(*enums).map(&f) end pp dot_product(x, y) puts '-'*10 pp mmap(x, y) {|a,b| a*b } pp mmap(x, y, [1, 2, 4]) {|a,b,c| a*b*c } puts '-'*10 pp cartesian_product(x, y)