From: Alex Gutteridge Date: 2013-02-13T01:55:12+09:00 Subject: Re: Select "columns" from multidimensional array? On 12.02.2013 13:06, Joel Pearson wrote: > Robert Klemme wrote in post #1096452: >>> So in short, my question is how can I return my class type after >>> using >>> Array's methods on my child-class? >> Do you mean as return value from #map and the like? Well, you can't >> without overriding all methods with this approach, I'm afraid. >> That's >> one of the reasons why this approach does not work well. :-) > > You're probably thinking in terms of classes which are constantly > active > as objects accessible to multiple users, whereas I'm just using this > class to make scripts easier to write. > > My usage in this case is: > > 1) Run a report which returns a table of data > 2) Filter the data on a set of criteria > 3) Output the results to Excel > 4) Exit > > Using the class I've built I can easily pare down the data to the > important sections, I've added other handy methods suitable to a > multidimensional array such as "find" which returns the header and > row, > "to_s" which converts to TSV format, and several more. It saves me > rewriting the same stuff over and over. > > It's great when I want to build excel-style tabs out of the data, > like > this little snippet: > ______________ > @data[:EXT] = @WIP_data.filter 'Job Status', /External Repair/ > @data[:Awaiting_Parts] = @WIP_data.filter 'Job Status', /Awaiting > Parts/ > > @data.each { |name, data| @data[:Summary].push [ name.to_str, ( > data.length -1 ) ] } > > reporter.output_to_excel_tabs @data, filename > ______________ > > Ok, in that case I'm happy with an array return, but there are plenty > of > sequential events where I'd like to have my own class type returned. > Is > passing it through the initializer again really the best way to do > that? As Robert says I'm not sure there is any (clean) way to do what you want, which is why delegation as opposed to inheritance is often used in this scenario. I'm sure this isn't a complete solution, but does this rewritten snippet (untested!) help at all? class ExcelSheet def initialize( val=[] ) val = %w(A1 B1 C1 A2 B2 C2 A3 B3 C3).each_slice(3).to_a if val == 'test' @arr = val end def skip_headers block_given? ? ( [ @arr[0] ] + yield( @arr[1..-1] ) ) : ( @arr[1..-1] ) end def filter( header, regex ) idx = @arr[0].index header @arr = skip_headers { |xl| xl.select { |ar| ar[idx] =~ regex } } end def method_missing(meth,*args,&block) ret = @arr.send meth, *args, &block ret.instance_of?(Array) ? ExcelSheet.new(@ret) : ret end end -- Alex Gutteridge