Greetings all.

Once upon a time I had a bunch of objects that all were included by one generic driver class. Each of these modules could provide some number of methods that the generic driver needs to know about, so that it would know to map a url to each method in the object.

Each of these 'page' objects may be written by any number of different programmers for any number of different projects. And all these programmers may be of different Perl skill levels.

So, the idea is to make the creation of these 'page' objects as simple and as straight forward as possible. I didn't want to have a 'provides' function that you had to list the public methods in because the first thing that is going to happen is that someone will leave one out, or mispell one, etc, etc.

Here is the solution I've come up with. Each 'page' class inherits from a parent class that uses a little symbol table evil to probe the child class and prepare the provides list for the driver object. I didn't do the probe in the driver because the symbol table trick made strict unhappy, so I used a very small base class that I could afford not to have strict in. It seems to do exactly what I need, but I'd like to have y'all's (pardon my southerner) feedback on the technique.

#/usr/bin/perl use strict; use inherited; use Data::Dumper; my $inherited = inherited->new(); print Dumper $inherited->{'provides'};
here is the parent object
package parent; sub new { my $class = shift; $class = ref($class) || $class; my $self = {}; $self->{'provides'} = mk_provides($class); bless($self, $class); return $self; } sub mk_provides { my $class = shift; # these are all the internal ones I've seen so far my %internal = map { $_ => 1 } qw (import isa ISA new BEGIN EN +D); $class .= "::"; local *stash; # here's the part that makes strict scream *stash = *{$class}; my @methods; foreach (keys %{*stash} ) { # if it's not an internal one or one that starts with +_ # add it to the list of public methods unless (defined $internal{$_} || $_ =~ /^_/) { push(@methods,$_); } } return \@methods; } 1;
and the 'page' object
package inherited; use strict; use base ("parent"); sub foo { } sub bar { } sub baz { } sub _private_method() { } 1;
And the output I get is exactly what I want.
$VAR1 = [ 'bar', 'foo', 'baz' ];
Any suggestions or thoughts are welcome.

/\/\averick


In reply to Request for review: OO, inheritance, and a symbol table trick. by maverick

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.