I have a basic question which I'm sure was discussed, but I'd like to see contemporary opinions about. As mine change often I'll asume others' / style do too, and would like to get a window on the current trend, if you may.
When writing object oriented code it is considered good style to assume that someday the class will be inherited. Should the inheriting class redefined the constructor, new trouble arises.
A minimal example would be
package Person;
sub new { bless { name => $_[1], job => $_[2] }, $_[0] }
sub name { $_[0]{name} }
sub job { $_[0]{job} }
package Person::Resumefied;
sub new { bless { name => $_[1], jobs => [ @$_[2] ] }, $_[0] }
sub jobs { @{$_[0]{jobs}} };
sub job { $_[0]{jobs}[$#{$_[0]{jobs}}] } # the last job is assumed cur
+rent
This way the original job method breaks, because the structure of the object has changed. But it's not in use, so that doesn't matter. But if we define a new method, which relies on the value of job:
package Person;
# ... other methods and such
sub cool { not $_[0]{job} =~ /programmer/ };
then calling the method cool, which needs the value of job, for a Person::Resumified object would break. As method calls are notorious for their speed it is not easy to find the method cool implemented so that it relies on the method job, and not on the hash value in the object:
sub cool { not $_[0]->job() =~ /programmer/ };
But (currently) i think this is better to do, especially if you're writing code which you intend to build on later. It is a safer way of working, obviously, but comes with a price - subroutine calls are slow in perl, and method calls
are slower, not just known as such:
nothingmuch% perl
use Benchmark qw(cmpthese);
our $self = Person->new();
cmpthese(10_000_000,{
direct => 'my $var = $self->{job}',
method => 'my $var = $self->job()',
});
package Person;
sub new { bless { job => 'not a programmer' },shift };
sub job { $_[0]{job} };
Benchmark: timing 10000000 iterations of direct, method...
direct: 10 wallclock secs ( 9.70 usr + 0.00 sys = 9.70 CPU) @ 10
+30927.84/s (n=10000000)
method: 39 wallclock secs (39.57 usr + 0.00 sys = 39.57 CPU) @ 25
+2716.70/s (n=10000000)
Rate method direct
method 252717/s -- -75%
direct 1030928/s 308% --
That's kinda... err.. bumming.
If you write production code where one method may be used in tight loops, and that method uses other values from within the object, which way would you choose to use?
Is it safe to assume that under heavy usage, say, a popular website driven by some cgi, the safe way of doing stuff will not cost more, or reduce responsiveness?
Thanks in advance,
Update: theorbtwo quoted my typo, and thus I've noticed and fixed it.
-nuffin
zz zZ Z Z #!perl
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: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.