From: Robert Klemme Date: 2004-03-18T18:19:33+09:00 Subject: Re: Can subclass have superclass method return instance of subclass schrieb im Newsbeitrag news:4058461D.22531.E498AB@localhost... > > > walter@mwsewall.com wrote: > > > > > class QArray < Array > > > def sum_e > > > inject(0){|sum, item| sum+=item.e} > > > end > > > end > > > > Why not just put sum_e into Array, instead of creating a subclass? > > That would then allow it to be accessed from any array object. > > > > class Array > > def sum_e > > ... > > end > > end > > > > ... > > sum = a.find_all {...}.sum_e > > > > That would work in this simple example... What I find is that I tend > to perform similar tasks on groups of Objects. If it's general enough module Enumerable is the place to put it: irb(main):001:0> module Enumerable irb(main):002:1> def sum_e; inject(0){|sum,i|sum+i}; end irb(main):003:1> end => nil irb(main):004:0> (1..10).to_a.sum_e => 55 irb(main):005:0> > We have classes that represent different objects in our domain ie > Customers, invoices, deliveries, etc... and we tend to perform > similar tasks on groups of these classes. Sum all invoices, find > invoices that are overdue, find most recent delivery, etc. If it's that special I'd do any of these: (i) Create a module of your own and extend collections: irb(main):001:0> module MyEnum irb(main):002:1> def sum_e; inject(0){|sum,i|sum+i}; end irb(main):003:1> end => nil irb(main):004:0> a=(1..10).to_a => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] irb(main):005:0> a.extend MyEnum => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] irb(main):006:0> a.sum_e => 55 (ii) Create a module (or multiple modules) of your own with the functions you need: irb(main):001:0> module EnumAlgorithms irb(main):002:1> def self.sum_e(enum); enum.inject(0){|sum,i|sum+i}; end irb(main):003:1> end => nil irb(main):004:0> EnumAlgorithms.sum_e( (1..10).to_a ) => 55 > I have created CustomerList, InvoiceLists, etc, so I can embed the > logic of the domain in one area and not have the same logic spread > throughout the application and ui layers. I really don't want to put > all of that logic in Array, plus then I'd have to do a lot of type > checking in many cases. In that case I'd probably choose option (ii) and put the algorithmic functions into the classes on which they operate, i.e. class InvoiceLists def self.sum(invoices) invoices.inject(0){|sum,inv| sum += inv.amount} end end etc. > Ruby has such beautiful Array functionality that I find I always end > up wanting to use it in my customized subclasses. Trying to convince methods that return Array to return something else will not work. Extending Array itself does work but should be done with care because IMHO only the most general functionality that applies to Arrays should be there. There are other better ways to solve this (see above). Kind regards robert