>>>>> "Brian" == Brian Reichert <[EMAIL PROTECTED]> writes:

Brian>   #
Brian>   # If called with an entry, get the OC names and continue
Brian>   #
Brian>   if ( UNIVERSAL::isa( $oc[0], "Net::LDAP::Entry" ) ) {
Brian>     my $entry = $oc[0];
Brian>     @oc = $entry->get_value( "objectclass" )
Brian>       or return;
Brian>   }

Brian> This test does not test to see if $oc[0] is of type 'Net::LDAP::Entry'.

It tests if it's a Net::LDAP::Entry, or anything inheriting from
Net::LDAP::Entry.  In other words, anything that should be able to do
everything an Net::LDAP::Entry does, and has at least all of the
member variables that a Net::LDAP::Entry object does.

Brian> In contrast, this test does:

Brian>   if ( ref($oc[0]) eq "Net::LDAP::Entry" ) ) {

And this kind of test is ALMOST ALWAYS WRONG.  It fails the "null
subclass" test... if I subclass a class without changing a single bit
of behavior, I should be able to replace an object of the parent type
with an object of the derived type and have it work perfectly.  The
"ref" solution breaks that.

Brian>   package qmailUser;

Your package names should not start with a lowercase.  That's
reserved for pragmata.

Brian>   use Net::LDAP::Entry;
Brian>   @ISA = qw(Net::LDAP::Entry);

Brian>   sub new {
Brian>     my $entry  = shift;
Brian>     my $class = ref($entry) || $entry;
Brian>     my $self = bless $entry->SUPER::new(), $class;
Brian>     $self;
Brian>   }

This code is unnecessarily complex.  First, to create a
subclass-overloaded ->new (for additional member variables), you
merely need:

    sub new {
      my $class = shift;
      my $self = $class->SUPER::new(@_);
      ... any additional things to $self ...
      return $self;
    }

But in your case, you have *no* additional attributes (member variables),
so you can leave your "new" entirely out, and it does The Right Thing.

Brian> What happens deep in Schema.pm, at that test, is that my scalar
Brian> value 'qmailUser' is not tested for type; instead UNIVERSAL::isa()
Brian> sees that these is a class 'qmailUser' that is subclassed from
Brian> 'Net::LDAP::Entry'.  And the unwanted behavior begins.

Brian> So - have I miscoded here, or have I ticked a bug in Net::LDAP::Schema?

If your objects cannot also respond to the entire protocol of
the base class, then you don't have a proper derived class.

Perhaps you want a "has-a" model instead of an "is-a" model.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<[EMAIL PROTECTED]> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

Reply via email to