<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-8859-1">
<META content="MSHTML 6.00.2800.1264" name=GENERATOR>
<STYLE>@page Section1 {size: 8.5in 11.0in; margin: 1.0in 1.25in 1.0in 1.25in; }
P.MsoNormal {
        FONT-SIZE: 12pt; MARGIN: 0in 0in 0pt; FONT-FAMILY: "Times New Roman"
}
LI.MsoNormal {
        FONT-SIZE: 12pt; MARGIN: 0in 0in 0pt; FONT-FAMILY: "Times New Roman"
}
DIV.MsoNormal {
        FONT-SIZE: 12pt; MARGIN: 0in 0in 0pt; FONT-FAMILY: "Times New Roman"
}
A:link {
        COLOR: blue; TEXT-DECORATION: underline
}
SPAN.MsoHyperlink {
        COLOR: blue; TEXT-DECORATION: underline
}
A:visited {
        COLOR: purple; TEXT-DECORATION: underline
}
SPAN.MsoHyperlinkFollowed {
        COLOR: purple; TEXT-DECORATION: underline
}
SPAN.EmailStyle17 {
        COLOR: windowtext; FONT-FAMILY: Arial
}
DIV.Section1 {
        page: Section1
}
</STYLE>
</HEAD>
<BODY lang=EN-US vLink=purple link=blue>
<DIV><SPAN class=218010112-08122003><FONT face=Arial color=#0000ff
size=2>Philip: Are you asking how to better solve this problem through
OOP, or are you asking for ways to improve your use of this object-oriented
module that someone else wrote? </FONT></SPAN></DIV>
<DIV><SPAN class=218010112-08122003><FONT face=Arial color=#0000ff
size=2></FONT></SPAN> </DIV>
<DIV><SPAN class=218010112-08122003><FONT face=Arial color=#0000ff size=2>If
you're asking how to solve your problems through OOP, I would recommend
creating a wrapper object that takes the value names you dislike and maps
them to names you DO like. This will encapsulate the offending code and
shield the rest of your project from it. There is currently no OOP code in
the sample you provided (other than your use of the 3rd party's object) so I'm
not sure what your comfort level is with Perl OOP. If you do want more
help on this, I can certainly provide it, but it will be a little more in-depth,
so I'll let you indicate that you need this before I get off on a long
tangent here.</FONT></SPAN></DIV>
<DIV><SPAN class=218010112-08122003><FONT face=Arial color=#0000ff
size=2></FONT></SPAN> </DIV>
<DIV><SPAN class=218010112-08122003><FONT face=Arial color=#0000ff size=2>If you
simply want to improve your own use of the object in question by improving the
code you provided, I would recommend that you look into the keys() and values()
functions, which will help you avoid having to enter your list of "lousy_names"
2 times. Try something like this:</FONT></SPAN></DIV>
<DIV><SPAN class=218010112-08122003><FONT face=Arial color=#0000ff
size=2></FONT></SPAN> </DIV>
<DIV><SPAN class=218010112-08122003><FONT face="Courier New"
size=2>%RecordParams = (</FONT>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT
face="Courier New"><SPAN class=218010112-08122003>
"</SPAN>lousy_name_1<SPAN class=218010112-08122003>"</SPAN> => <SPAN
class=218010112-08122003>"</SPAN>Meaningful name 1<SPAN
class=218010112-08122003>"</SPAN>,</FONT></SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT
face="Courier New"><SPAN class=218010112-08122003>
"</SPAN>lousy_name_2<SPAN class=218010112-08122003>"</SPAN> => <SPAN
class=218010112-08122003>"</SPAN>Meaningful name 2<SPAN
class=218010112-08122003>"</SPAN>,</FONT></SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT
face="Courier New"><SPAN class=218010112-08122003>
"</SPAN>lousy_name_3<SPAN class=218010112-08122003>" </SPAN>=> <SPAN
class=218010112-08122003>"</SPAN>Meaningful name 3<SPAN
class=218010112-08122003>"</SPAN>,</FONT></SPAN></P>
<P class=MsoNormal><FONT face="Courier New" size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">);</SPAN></FONT></P>
<P class=MsoNormal><FONT size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT> </P>
<P class=MsoNormal><FONT face="Courier New"><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><SPAN class=218010112-08122003>#
Perl requires lowercase "sub", not "Sub"!</SPAN></SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT face="Courier New"><SPAN
class=218010112-08122003>s</SPAN>ub printRecordDetails {</FONT></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT
face="Courier New"><SPAN class=218010112-08122003> </SPAN>my
$record = shift;</FONT></SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><SPAN
class=218010112-08122003><FONT face="Courier New"> # keys()
will return the array ( "lousy_name_1", "lousy_name_2", "lousy_name_3" ) based
on what</FONT></SPAN></SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><SPAN
class=218010112-08122003><FONT face="Courier New"> # you
have assigned as keys for the %RecordParams hash. values() would
return</FONT></SPAN></SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><SPAN
class=218010112-08122003><FONT face="Courier New">
# the array ("Meaningful Name 1", etc...
)</FONT></SPAN></SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT
face="Courier New"><SPAN class=218010112-08122003>
</SPAN>foreach my $line ( <SPAN
class=218010112-08122003>keys(%RecordParams) </SPAN>) {</FONT></SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT
face="Courier New"><SPAN
class=218010112-08122003> </SPAN>print
$RecordParams{$line} . <SPAN class=218010112-08122003>"</SPAN>
= <SPAN class=218010112-08122003>"</SPAN> . $record->param($line)
. <SPAN class=218010112-08122003>"</SPAN>\n<SPAN
class=218010112-08122003>"</SPAN>;</FONT></SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT
face="Courier New"><SPAN class=218010112-08122003>
</SPAN>}</FONT></SPAN></P>
<P class=MsoNormal><FONT face="Courier New" size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">}</SPAN></FONT></P></SPAN></FONT>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT> </P>
<P class=MsoNormal><FONT color=#0000ff><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><SPAN
class=218010112-08122003>Another thing you might try is ditching the subroutine
and using:</SPAN></SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial><FONT size=2><SPAN
class=218010112-08122003></SPAN></FONT></FONT><FONT><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><SPAN
class=218010112-08122003></SPAN></SPAN></FONT> </P>
<P class=MsoNormal><FONT><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><SPAN
class=218010112-08122003><FONT face="Courier New">for my $record ( <SPAN
class=218010112-08122003>keys(%RecordParams) </SPAN>) {</FONT></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT
face="Courier New"><SPAN class=218010112-08122003>
</SPAN>foreach my $line ( @RecordOrder) {</FONT></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT
face="Courier New"><SPAN
class=218010112-08122003> </SPAN>print
$RecordParams{$line} . <SPAN class=218010112-08122003>"</SPAN>
= <SPAN class=218010112-08122003>"</SPAN> . $record->param($line)
. <SPAN class=218010112-08122003>"</SPAN>\n<SPAN
class=218010112-08122003>"</SPAN>;</FONT></SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT
face="Courier New"><SPAN class=218010112-08122003>
</SPAN>}</FONT></SPAN></P></SPAN></SPAN></SPAN></FONT>
<P class=MsoNormal><FONT face="Courier New"><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><SPAN
class=218010112-08122003>}</SPAN></SPAN></FONT></P>
<P class=MsoNormal><FONT><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><SPAN
class=218010112-08122003></SPAN></SPAN></FONT> </P>
<P class=MsoNormal><FONT color=#0000ff><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><SPAN
class=218010112-08122003>That's much more readable and succinct. It
actually cuts your script down to around 12 lines (not counting comments and
white space).</SPAN></SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT> </P></SPAN></DIV>
<DIV><SPAN class=218010112-08122003></SPAN><FONT face=Arial color=#0000ff
size=2><SPAN class=218010112-08122003>As far as I can tell, there's no
multidimensional array being used by your 3rd party object. In fact,
Perl doesn't support them. It only supports arrays of arrays, which can be
used to solve similar problems, anyhow, and can often appear to be
multi-dimensional. Fortunately, it doesn't look like you'll have to deal
with that kind of complexity here.</SPAN></FONT></DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN
class=218010112-08122003></SPAN></FONT> </DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN class=218010112-08122003>What
you get by accessing $object->{"Record"} is a single dimensional array
of objects. Each of these objects seems to have a "param" method that
allows you get the value of a single field of the record. I
agree this could have been much better designed.</SPAN></FONT></DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN
class=218010112-08122003></SPAN></FONT> </DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN class=218010112-08122003>I
would prefer to see something like this:</SPAN></FONT></DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN
class=218010112-08122003></SPAN></FONT> </DIV>
<DIV><FONT face=Courier size=2><SPAN class=218010112-08122003>while ( my $record
= $object->getNext() ) {</SPAN></FONT></DIV>
<DIV><FONT face=Arial size=2><SPAN class=218010112-08122003><FONT
face=Courier> foreach my $line (
@RecordOrder ) {</FONT>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT
face=Courier><SPAN
class=218010112-08122003>
</SPAN>print $RecordParams{$line} . " = " . $record->param($line) .
"\n";</FONT></SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT
face=Courier><SPAN
class=218010112-08122003>
</SPAN>}</FONT></SPAN></P></SPAN></FONT></DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN
class=218010112-08122003></SPAN></FONT> </DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN class=218010112-08122003>This
creates a getNext() method that returns the appropriate record object when
called and moves an internal pointer to the next record in the object's array
list. Another option would have been:</SPAN></FONT></DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN
class=218010112-08122003></SPAN></FONT> </DIV>
<DIV><FONT face=Arial size=2><SPAN class=218010112-08122003>
<DIV><SPAN class=218010112-08122003><FONT face=Courier>while
($object->moveNext() ) {</FONT></SPAN></DIV>
<DIV><FONT size=2><SPAN class=218010112-08122003><FONT
face=Courier> foreach my $line (
@RecordOrder ) { </FONT>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT
face=Courier><SPAN
class=218010112-08122003>
</SPAN>print $RecordParams{$line} . " = " . $<SPAN
class=218010112-08122003>object</SPAN>->param($line) .
"\n";</FONT></SPAN></P>
<P class=MsoNormal><SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><FONT
face=Courier><SPAN
class=218010112-08122003>
</SPAN>}</FONT></SPAN></P></SPAN></FONT></DIV></SPAN></FONT></DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN
class=218010112-08122003></SPAN></FONT> </DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN class=218010112-08122003>This
form removes the need for the "$record" object to be provided. You just
use the "$object" object and that's all.</SPAN></FONT></DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN
class=218010112-08122003></SPAN></FONT> </DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN
class=218010112-08122003>Requiring consumers of your OOP code to use the
$object->{"Record"} form of accessing your object's data is catastrophically
bad form unless you're both the author of the OOP code and the only
consumer of it. This is somewhat equivalent to using public variables
in object-oriented Java, C++, or VB code and expecting your consumers to use
them. It's a recipe for disaster.</SPAN></FONT></DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN
class=218010112-08122003></SPAN></FONT> </DIV>
<DIV><FONT face=Arial color=#0000ff size=2><SPAN
class=218010112-08122003>jpt</SPAN></FONT></DIV>
<DIV><FONT face=Tahoma><FONT face=Arial color=#0000ff size=2></FONT> </DIV>
<DIV><BR><FONT size=2><SPAN class=218010112-08122003><FONT face=Arial
color=#0000ff> </FONT></SPAN>-----Original Message-----<BR><B>From:</B>
Phillip Tyre [mailto:phillip.tyre@fcul.com]<BR><B>Sent:</B> Friday, December 05,
2003 10:55 AM<BR><B>To:</B> tallahassee-pm@mail.pm.org<BR><B>Subject:</B>
[Tallahassee-pm] Perl, a better way to do this with
OOP<BR><BR></DIV></FONT></FONT>
<BLOCKQUOTE dir=ltr
style="PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #0000ff 2px solid; MARGIN-RIGHT: 0px">
<DIV class=Section1>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">It's not that I'm not a huge fan
of the object oriented parts of Perl, I'm just not that versed in it. That
said, I find my self working on a for fun project that uses a lot of OOP. I'm
trying to get up to speed, and I have something that almost works, but it's
not elegant. It's also not very readable!</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT> </P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">I started with a program someone
else had written to walk through the object and print out the
information.</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Abstracting it a bit, it looks
like this:</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT> </P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
I have a library that someone else wrote that unpacks a binary file into an
object.</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
# I get an object containing the file contents with:</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
my $object = Module:Method->new_object_from_file(file);</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT> </P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
# The names used by the object are not the best in the world, so we have a
line like this:</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT> </P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
%RecordParams = (</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
"lousy_name_1" => "Meaningful name 1",</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
"lousy_name_2" => "Meaningful name 2",</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
"lousy_name_3" => "Meaningful name 3",</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
);</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT> </P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
# Then we create a new array with:</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
@RecordOrder = qw ( lousy_name_1 lousy_name_2 lousy_name_3
);</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
T# hen we have a subroutine to print out the info for a
record:</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
Sub printRecordDetails {</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
my $record = shift;</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
foreach my $line ( @RecordOrder) {</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
print $RecordParams{$line} . " = " . $record->param($line) .
"\n";</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
}</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
}</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT> </P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
# Use a method of the object to return a (multidimensional?) array of all the
records.</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
my @records = @{$object->{"Record"}};</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT> </P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
# Then we call the subroutine in a loop for each record</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
for my $record ( @records ) {</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
printRecordDetails( $record );</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT> </P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
# end</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></FONT> </P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">And that's it, now keep in mind
this is an example script provided by someone else to make use of the library.
It just doesn't seem like the best way to do things, but I suppose I don't
know enough about OOP to know what questions to ask to find answers to make it
better.</SPAN></FONT></P>
<P class=MsoNormal><FONT face=Arial size=2><SPAN
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
</SPAN></FONT></P></DIV></BLOCKQUOTE></BODY></HTML>