Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: Class::Interface -- isa() Considered Harmful

by BrentDax (Hermit)
on Jan 17, 2003 at 08:18 UTC ( [id://227630]=note: print w/replies, xml ) Need Help??


in reply to Class::Interface -- isa() Considered Harmful

I'd personally rather say "Make sure this object can handle any message I can send an Arcade." Since the Airport contains an Arcade, it will just delegate methods like colle­ct_qu­arter­s and play_­annoy­ing_d­ance_­music to the Arcade it contains.
Why should an Airport act as an Arcade?

As an example, let's pretend a mall has a skate park in it. I don't think that the mall should act as a skate park in any way--unless you're writing a Tony Hawk game. :^)

Going back to interfaces, the one thing I see them as being useful for in a language that supports MI is for specifying properties of a class (in the Perl 6 sense of the word). For example, in .NET any serializable class implements the ISerializable interface. (I've probably got some karmic justice coming soon for suggesting that an M$ design is good... ;^) )

Personally, I would standardize on a 'get_arcade' method for when you're handed something that isn't an Arcade:

$arcade=$arcade->get_arcade until $arcade->isa('Arcade');

=cut
--Brent Dax
There is no sig.

Replies are listed 'Best First'.
Re: Re: Class::Interface -- isa() Considered Harmful
by chromatic (Archbishop) on Jan 17, 2003 at 17:28 UTC

    It was an unclear example.

    I hesitate to use this example, knowing that the likely response will be "Tying won't work that way in Perl 6." To forestall those replies, I know that this is the case. I'm also not interested in questions of "Why are you doing this anyway?" This is an example of the shortcomings of relying on inheritance. I can come up with clever hacks to get around all this, but I would rather that I not have to do so.

    If you do have a better solution that achives both of my goals (it should be possible to check that things can handle the operations I'm about to perform on them, and this check should not dictate the implementation of these operations), I'm all ears.

      As I pointed out in another node in this node tree, you seem to be looking for:

      use Scalar::Util qw(reftype); sub new { my($class, $args) = @_; return unless $args; return unless reftype($args) eq 'HASH'; # ...

      Also, it looks as if you are trying to blur the line between Perl object interfaces and Perl blessed reference method interfaces. Since the two are fully independent (any Perl blessed reference can be implemented using a reference to any Perl object), I suggest you are asking the wrong question... :-)

      To expand upon my "any Perl blessed reference can be implemented using a reference to any Perl object" - the initial version of my class could use a HASH to store member fields, while a later version uses an ARRAY to improve on efficiency, and reduce storage requirements. In pure OO philosophy, your code should not rely on how my class stores its member fields. If your code is expecting to get a hash reference as an argument, it is my responsibility as the caller to pass you a hash reference. If my hash reference happens to be blessed, it shouldn't matter. You should use reftype() and not care about the blessed'ness of the structure. It is unfortunate that Scalar::Util was not included in earlier versions of Perl.

        No, I am very much not looking for Scalar::Util::reftype, thought it could indeed replace UNIVERSAL::isa. It still dictates implementation, which is what I'm trying to avoid.

        I'm not expecting to rummage around in the internals of an object passed as $args. I'm expecting to deal with something that behaves as a hash. If it's a hash, fine. If it's a tied hash, it ought to work fine too.

        Unfortunately, it doesn't:

        #!/usr/bin/perl -w use strict; use Scalar::Util 'reftype'; use Tie::Hash; foreach my $package (qw( Scalar Array Code )) { my $h = tie my %new_hash, $package . 'Hash'; print "Tied $h as a hash based on $package\n"; print 'It is ' . (UNIVERSAL::isa( $h, 'HASH' ) ? '' : 'not ') . "a + HASH\n"; print 'Its reftype is ' . reftype( $h ) . "\n"; } package ScalarHash; sub TIEHASH { bless \(my $foo), $_[0] } package ArrayHash; sub TIEHASH { bless [], $_[0] } package CodeHash; sub TIEHASH { bless sub {}, $_[0] }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://227630]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (10)
As of 2024-03-29 15:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found