From: Brian Candler Date: 2009-07-21T22:35:27+09:00 Subject: Re: Mean method Älphä Blüë wrote: > http://pastie.org/553287 Are you posting here because you want comments/suggestions? If so, here's my 2c. (1) Passing enumerated values 1,2,3 is not very Ruby-like. If you want to go this way, then I'd suggest symbols: :arithmetic, :geometric, :harmonic (2) However, IMO it's also code smell if you write something like case A when X .. do one thing when Y .. do another thing ... etc end There's usually a better way to ask directly for what you want. Suggestions: (a) add some methods directly to class Array, in the same way as 'sum' class Array def arithmetic_mean self.sum / self.size end def geometric_mean ... etc end end puts [1,2,3,4,5].arithmetic_mean This is perfectly fine within your own apps, but modifying core classes may not be acceptable in a shared library (depending on who your target audience is) (b) wrap an array with an object which does the calculation class Mean def initialize(arr) @arr = arr end def arithmetic @arr.sum / @arr.size end ... etc end puts Mean([1,2,3,4,5]).arithmetic Note that creating an object like this is a cheap operation in Ruby. You're not copying the array elements, just a reference to the array itself. (3) It is considered extremely bad form to write if !an_array.is_a? Array: raise "mean(#{an_array}) error: #{an_array} is not an array." end You should simply leave this out. This lets the user pass in any object which responds to the particular methods you call on it (each, sum, size). This is the "duck typing" principle - if someone wants to create an object which behaves like an Array, even though it is not actually an Array, why should you forbid them from using it? If they pass in an incompatible object, Ruby will generate an exception for you anyway. Admittedly it might not be quite as obvious what's happening, but it will typically be something along the lines of NoMethodError: object does not respond to 'sum' which tells you exactly what the problem is. (4) You can rewrite the following using inject: an_array.each do |a| n_sum += (1.0 / a) end (5) If I were you, I would rewrite this not to use sum and size, but just to iterate over the collection using 'each' (or something which in turn calls 'each', like 'inject'), calculating the total and count as you go. This would allow your code to work on any object which is Enumerable, such as (1..5).arithmetic_mean Regards, Brian. -- Posted via http://www.ruby-forum.com/.