Dear monks,
I have a whole bunch of different objects; for example "node" objects, which can go into a "tree" object, which can go into a "trees" (note: plural) object. The underlying data structures for the "tree" and "trees" objects are array refs. Likewise, I also have "datum" objects, which go into a "matrix" object, which go into a "matrices" object. Again, the "matrix" and "matrices" objects are blessed anonymous array refs.
Now, all objects that are blessed array refs inherit from the abstract "listable" object, which has a bunch of methods that are handy for array-like structures (for example filters, where you loop through all entities in the array and return all entities that meet a certain condition). I also want to be able to have a listable method "insert", with the following behaviour:
$tree->insert($node); #works
$matrix->insert($datum); #works
$trees->insert($node); #error: $trees object can't contain $node
$matrix->insert($node); #error: $matrix object can't contain $node
Also, I want this
Listable::insert method to have the following properties:
- No hard-coded ref $object eq ... trickery
- No pile of if / elsif / elsif ... duck-typing mess for all possible permutations of nodes, trees, matrices etc...
...so that the method also works for "specialnode" objects that inherit from the "node" object (for example).
Here's what I did to achieve this: all objects have two methods that return strings to indicate i) what "container_type" the object is; ii) what type of "container" it can be inserted into. Then, internally, the
Listable::insert method becomes sort of like this:
sub insert {
my ( $self, $obj_to_insert ) = @_;
if ( $self->container_type eq $obj_to_insert->container ) {
push(@{$self}, $obj_to_insert);
}
else {
die "I can't hold that object!";
}
}
The downside of this is that every insertion involves two method calls and a string comparison. Also, it feels a bit hokey, I think.
So now my question: can anyone recommend a more elegant and efficient way to achieve the same behaviour?
Thanks!
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.