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=$class.new(*%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.

=cut
--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

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



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.