FW: SPUG: Scope question
dancerboy
dancerboy at strangelight.com
Wed Jun 12 15:44:32 CDT 2002
At 9:46 am -0700 2002-06-12, Peter Darley wrote:
>Friends,
> As they say, there's more than one way to do it...
>
>Jason said:
>> Yes, you should consider this an opportunity to rethink your coding
>> style and perhaps learn better coding techniques. As any experienced
>> programmer should be able to tell you, global variable are a Bad
>> Thing. Many languages (e.g. Java) don't even have globals.
>
> I agree, there is always room to improve ones coding techniques. One
>reason that I want to use the globals is that I've gotten mixed results with
>passing around hash references and as hashes, and I'm not comfortable with
>my understanding of when elements of a hash are copied, when the elements of
>a copied hash are just references to the real contents of the hash, etc. I
>figured it would be simpler to rely on globals to ensure that every time my
>session info hash gets used I know that it's the correct one.
So consider this an opportunity to clarify your understanding of
values vs. references in Perl :) (Pointless aside: if you think
Perl references are confusing, you should try coding in PHP some
time. That "language" has got to have the most hideous reference
syntax/semantics ever devised...)
If topics such as references and OO Perl still seem a little fuzzy, I
would highly recommend "Advanced Perl Programming" from O'Reilly (the
"Black Panther Book"): IMO it explains these topics (and many
others) much better than perldoc.
>
>Then Jason said:
>> That might be reasonable advice for non-OO languages. I still say
>> that with OO languages, there is *no* good reason for using globals.
>> Pass the database handle to an object constructor once, and then the
>> client can forget about it after that -- or else get the handle from
>> a class method. Ditto with configuration data.
>
> I don't write OO Perl, as I don't see any particular value in it unless
>you're putting modules out into the wild. I find it far easier to conceive
>of functions as being things that transform data, so I can have any number
>of functions that get data into a certain state before passing it off to
>another function.
On the one hand, I can sympathize. I first learned to code long
before there was any such thing as OOP, and it took me a lot of
practice and effort to learn to think in OOP terms instead of in
functional programming terms. But I can tell you from personal
experience that it's worth the effort. My OO code is *much* easier
to debug, maintain, and extend than code I've written functionally.
I still find myself sometimes slipping back into my old
functional-programming habits, and the results are almost always poor
code.
>The other option seems to be having either tons of
>objects that are very similar, but have different methods of initialization
>and/or processing, or having small numbers of huge unwieldy objects that
>break the idea of having an object fundamentally doing one thing
This is probably an indication that you're still thinking and coding
in functional-programming terms. I see this a lot in CPAN modules:
the authors of the modules use classes simply as namespaces for
functions, rather than for true encapsulation; and the results are
exactly what you describe: a small number of huge, unwieldy objects.
(A perfect example is the ubiquitous but utterly grotesque CGI.pm, in
which *everything* is made part of a "CGI" object. I've been coding
CGI scripts in Perl since '96, and I still haven't got the foggiest
idea what exactly a "CGI" object is supposed to encapsulate.)
But here's a clue as to where your thinking is still functional
rather than OO: an object does not fundamentally *do* one thing, an
object fundamentally *is* one thing. A well-designed class should
encapsulate some identifiable entity. An object may *do* lots of
different things -- as many things as the entity that it encapsulates
-- but it shouldn't *be* lots of different things. The difference is
subtle but important.
If you have tons of classes that are very similar, that's a good
indication that they should probably be subclasses of a common base
class: the behaviour they have in common can be coded into the base
class, and incorporated via inheritance, while the behaviour that's
unique to each class can be coded into the subclasses.
OTOH, if you have a small number of huge, unwieldy objects, that's a
good indication that you should be using composition. If your class
has a huge number of simple data and/or function members, it probably
makes sense to encapsulate those members into classes of their own.
Instead of having a huge number of simple data and/or function
members, your class can have a small number of members which are
themselves objects, whose members may themselves be objects, and so
on to whatever depth is necessary so that no one class becomes too
big and unwieldy. E.g. instead of trying to encapsulate everything
that a SQL-speaking database can do into a single gargantuan Database
object, your Database object can be composed of Table objects, which
are themselves composed of Row objects, which are themselves composed
of Field objects. So instead of:
$database->get_field_from_row_from_table(
$field_name, $primary_key, $table_name
)
you would have:
$database->get_table( $table_name )->get_row( $primary_key )->get_field(
$field_name
)
Each of these classes -- Database, Table, Row, Field -- would be
fairly simple, yet by chaining together accessor functions (as in the
above example) a single Database object can indirectly encapsulate a
*huge* amount of functionality.
Does that make sense?
-jason
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
POST TO: spug-list at pm.org PROBLEMS: owner-spug-list at pm.org
Subscriptions; Email to majordomo at pm.org: ACTION LIST EMAIL
Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
For daily traffic, use spug-list for LIST ; for weekly, spug-list-digest
Seattle Perl Users Group (SPUG) Home Page: http://seattleperl.org
More information about the spug-list
mailing list