Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

Imagine for a moment that you're writing the billing component of an online store. Now, there are several ways a customer can pay: they can use a credit card, a debit card, a check, etc. You could use a switch statement (or an if/elsif chain in Perl 5) to do it:

given ($payment_method) { # All code samples are Perl 6 when 'credit' { do_credit_card($num, $exp) } when 'debit' { do_debit_card($num, $exp) } when 'check' { do_check() } default { die } }

But maybe there are several steps involved--early in the process you have to authorize, then later you have to execute the transaction, and perhaps you need to store the info in a database so crackers can steal it. That requires three switch statements in different areas of the code. And then six months down the road, you want to add PayPal support, so you have to change three different switch statements, but in one of them you accidentally put 'payapl', but it's already gone into production so the company loses five thousand dollars and fires you.

You don't want to get fired.

So instead, you write an object to represent a payment method, and a subclass for each specific way of paying:

class MyStore::PayMethod { # A submethod is a method that isn't inherited. submethod new { die "Create a subclass, silly." } method authorize($price) { ... } method execute($price) { ... } method store($dbh) { ... } } class MyStore::PayMethod::CreditCard is MyStore::PayMethod { # Colon means private--only code in this class can see # it. has ($:ccnum, $:ccexp, $:ccname); submethod BUILD($:ccname, $:ccnum, $:ccexp) {} method authorize($price) { (code to authorize) } method execute($price) { (code to execute) } method store($dbh) { (code to store) } }

Now you can create the appropriate object exactly once:

my $class; given($payment_method) { when 'credit' { $class=MyStore::PayMethod::CreditCard } when 'debit' { $class=MyStore::PayMethod::DebitCard } when 'check' { $class=MyStore::PayMethod::Check } } my $payobj=$*%params);

And then later on, when it's time to authorize, all you need to do is put the statement $payobj.authorize()--no nasty switch required.

In essence, an object is a way to make tasks with different data look the same to the outside world, even if the exact algorithm used to do that task to that data is radically different. It's a little like passing around a table of functions, only cleverer.

Edit: a friendly elder reminded me that has requires parens when declaring multiple attributes, just like my and our in Perl 5.

--Brent Dax
There is no sig.

In reply to Re^3: Perl 6, Object Orientation and Melting Brains by BrentDax
in thread Perl 6, Object Orientation and Melting Brains by willyyam

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (6)
As of 2022-07-05 13:04 GMT
Find Nodes?
    Voting Booth?

    No recent polls found