On Monday, July 05, 2010 03:30:44 pm Fearless Fool wrote: > Assume I'd like to create a statistics package designed to work on > Arrays [but see P.S.]. One way to do this would be to create functions > that take an array as an argument: > > def mean(array) > return NaN unless array && array.size > 0 > array.reduce(0.0) {|accum, val| accum + val} / array.size > end > > ... but that's so old school. What I'd really like is to *cleanly* > > extend the Array class so you can operate on it directly, as in: > >> [1, 2, 3].mean > > => 2.0 > > I'm sure that it's considered bad style to simply open the Array class > and extend it, since that can lead to unexpected user surprises: > > class Array > def mean > return NaN unless self.size > 0 > self.reduce(0.0) {|accum, val| accum + val} / self.size > end > end What kind of surprises? > My hunch is that the stats functions should be wrapped in a module and > then included (extended?) when desired. But despite reading the > tutorials and docs, I'm not sure what's considered the stylistically > correct way (and the syntax) to package that up. Simple enough: module MyModule def mean ... end end Then, you can always do this: [].extend MyModule Or this: class Array include MyModule end Then, probably, provide a file people can 'require' that'll do the inclusion for them, maybe even make that the default. It might also be nice to provide a way to do this on Enumerables, though that would be less efficient if you know you have an array. For example: def mean size = 0 count = inject(0){|accum, val| size+=1; accum+val} count / size.to_f end