ara.t.howard / noaa.gov wrote:
> On Sun, 26 Mar 2006, Joel VanderWerf wrote:
> 
>> The point about coupling (mentioned in the second-to-last paragraph of
>> the
>> article) is important, and I feel it is dismissed to easily in the
>> article.
>> There are some tradeoffs to consider, though perhaps they are out of the
>> scope of the article, which is intended as an exercise, not as a complete
>> guide:
>>
>> 1. Suppose your code needs to _discover_ what fields are in the file? 
>> You
>> can use #instance_methods(false), but that is not perfect: you have to
>> filter out "to_s" and "inspect", which were added by #make. And what
>> if you
>> add a new method in addition to the ones generated by #make? The field
>> names
>> could be stored in a list kept in class instance variable...
>>
>> 2. Once you have discovered the field names, you have to use
>> send(fieldname)
>> and send("#{fieldname}=") to access them. That's more awkward and (at
>> least
>> in the second case) less efficient than Hash#[] and #[]=. Who's the
>> "second
>> class citizen" in this case?
>>
>> 3. If you really know the field names "in advance" (that is, you have
>> enough
>> information to hard code them into your program), rather than "by
>> discovery", then maybe it is better to use a different metaprogramming
>> style
>> in which the fields are declared using class methods:
>>
>>  class Person
>>    field :name, :favorite_ice_cream, ...
>>  end
>>
>> In this way, some rudimentary error checking can be performed when
>> reading
>> the file, rather than failing later when trying to serve ice cream to the
>> person. (I just hate it when my ruby-scripted robo-fridge serves me
>> passion
>> fruit and rabbit dropping ice cream.) This is not always the best way
>> to go
>> (what if, as the article points out, fields get added to the file?),
>> but one
>> more thing to keep in mind.
> 
> i'm totally with you on this joel.  still, i think one can have a bit of
> both:
...
>     class CSVTable < ::Array
>       attr "fields"

Sure, that's more or less what I meant by storing the fields, but I was
thinking of using a class instance variable to keep that information at
the class level (assuming you might want to reuse one table class and
one row class for several files).

Using arrayfields is nice, since you have the symbolic #[] and #[]=
interfaces, as with hashes, as well as the array interface. But you have
neither a declared list of what fields should be in the file (what I was
suggesting for error checking purposes), nor the ability to refer to
fields directly with a "first class citizen" method (what Hal's article
was advocating):

p table[1].latitude

Nothing wrong with any of these approaches, it's just good to be aware
of all of them.

Btw, you can use a block with #any? :

>         return(send(m)) if [String, Symbol].map{|c| c === m}.any? &&
> respond_to?(m)

    return(send(m)) if [String, Symbol].any? {|c| c === m} && respond_to?(m)

-- 
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407