So it's potentially not a great candidate for OOP?
Basically, i'm writing a Spreadsheet to Template program. I've already done it without OOP, but i thought it'd be good to have each line of the spreadsheet as an object.
In other words, I take a config file with a list of the column headings/titles. The program reads the sheet and finds the title row. Each line of the spreadsheet then becomes a hash where the key is the title, and the value is the spreadsheet value. It's then really easy to build templates from the spreadsheet. I use it a lot.
I figured i'd have each line of the spreadsheet as an object and then i could have lot's of little methods i could directly call from the template to modify the data. (Split lists etc).
The problem being i don't know what the title would be so i don't know how i'd access each attribute. The template would know as it would be written by the user in reference to the spreadsheet/config file.
Bad idea to use OOP?
Thanks for all your replies
| [reply] |
To me it sounds like a hash would be a perfectly fine representation of a spreadsheet line. If you do it with dynamically created accessors, the program using the spreadsheet-line class would either have to find out which methods are supported, which doesn't offer any advantage over using a plain hash, or it would need to know the names of the columns you'll be using in advance.
If you want to do it the OO way, you could have a method "fields" or so that returns an array of strings, and one "get_field" that you can pass a field name and it retrieves the value. Unless the class does something smarter on top of that though, that's completely identical to what a plain hash does, just slower and more verbose.
| [reply] |
One of the dangers with dynamic fields is the potential for collision (what if a column is titled "new"?). However, if you wish to try it out anyway, I would use AUTOLOAD. The example in the documentation does exactly what you want (though note the comment that says "this is a terrible way to implement accessors").
| [reply] |
By the way: One advantage that an object might have over a plain hash is that typos in the column names cause errors. However, you can get that effect even with a hash, with the core module Hash::Util:
$ perl -wMstrict
use Hash::Util qw/lock_keys/;
my $row = { foo=>3, bar=>7 };
lock_keys %$row;
print "$$row{foo}\n";
print "$$row{bsr}\n";
__END__
3
Attempt to access disallowed key 'bsr' in a restricted hash at - line
+5.
| [reply] [d/l] |
Ok, I see what you're trying to do. Initially I wasn't sure if OO made sense, because part of the reason of having a class is that it presents a well-defined API. If the methods available on an object begin varying, you lose the advantage of a clearly defined API (and with a hash, one can at least use the keys function to see what keys are present). But if the methods are defined by the column names in a spreadsheet, then presumably the user knows what those column names are, so it's not so bad.
So, you could do it with OO; I the way I would look at it is this: Your object could have a generic get_column method, like ->get_column("column_name"), and a get_columns method that lists the available column names (so far, we've just re-created a hash-like interface). Then, your object could provide dynamically created ->column_name methods as syntactic sugar for ->get_column("column_name"). So far I think this is what you are planning? Problem 1: What if the column name overlaps with an existing method? For example a column named get_column, or isa (inherited from UNIVERSAL). Problem 2: Method calls don't interpolate in strings, while hash lookups do ("$foo->bar" vs. "$foo{bar}").
So sure, you could use an object, but unless your object would provide more functionality that you haven't mentioned yet, I don't yet see the advantage.
(P.S. I see mbethke and duelafn posted similar thoughts while I was typing :-) )
| [reply] [d/l] [select] |