Hi,
On Thursday 03 June 2004 21:29, Brian Reichert wrote:
> I've tried to search the archives on Geocrawler, but they seem to
> be havng issues right now.
>
> Anyway: I see throughout (for example) of Schema.pm version (0.9902)
> tests like this:
>
> #
> # If called with an entry, get the OC names and continue
> #
> if ( UNIVERSAL::isa( $oc[0], "Net::LDAP::Entry" ) ) {
> my $entry = $oc[0];
> @oc = $entry->get_value( "objectclass" )
> or return;
> }
>
> This test does not test to see if $oc[0] is of type 'Net::LDAP::Entry'.
>
> In contrast, this test does:
>
> if ( ref($oc[0]) eq "Net::LDAP::Entry" ) ) {
>
> The differences in these tests bit me during code development. I
> may have violated some perl coding convention, so this all may not
> be a bug in Schema.pm, but a failure on my part.
>
> I wanted to present a class that would provide a simplified interface
> to the 'qmailUser' object class in the qmail schema for qmail-ldap.
>
> I decided to subclass Net::LDAP::Entry:
>
> package qmailUser;
>
> use Net::LDAP::Entry;
> @ISA = qw(Net::LDAP::Entry);
>
> sub new {
> my $entry = shift;
> my $class = ref($entry) || $entry;
> my $self = bless $entry->SUPER::new(), $class;
> $self;
> }
>
> Within that package, I wanted to collect a list of MAY attributes:
>
> sub load_attributes {
> my $ldap = Net::LDAP->new ( $server ) ||
> croak "$0: can't connect to LDAP server $server: $!\n";
>
> my $result = $ldap->bind();
> $result->code && croak "failed to bind: ".$result->error ;
> my $schema = $ldap->schema();
>
> my $oc = 'qmailUser';
> my @may = $schema->may($oc);
> }
>
> What happens deep in Schema.pm, at that test, is that my scalar
> value 'qmailUser' is not tested for type; instead UNIVERSAL::isa()
> sees that these is a class 'qmailUser' that is subclassed from
> 'Net::LDAP::Entry'. And the unwanted behavior begins.
>
> So - have I miscoded here, or have I ticked a bug in Net::LDAP::Schema?
>
> By merely renaming my package to QmailUser, everything works, but
> I don't like the dissociation of my package name from what I intended
> to manipulate...
>
> I'd appreciate any feedback.
>
> Oh: this is for perl 5.005_03, if that's a factor...
I tried to rreproduce the problems on my system (Perl 5.8. BTW) and
I think you have been hit by a bug.
Unfortunately your diagnosis is not correct.
Let me try to give the correct one.
Perl has the ability to treat strings as symbolic refernces. I.e. when Perl
expects a reference and is not given a real (hard) reference but only
a scalar variable, it interprets the variable as a string naming a reference.
By naming your obhectclass te same as the attribute you tricked
UNIVERSAL::isa(...), which expects a reference as the first argument, into
believing you gave it a soft reference to your object class instead of the
name of a variable.
As a workaround you may change the name of your objectclass so that it is
different from all the variable names you pass to Net::LDAP::Schema->may()
But the correct solution is to change
if ( UNIVERSAL::isa( $oc[0], "Net::LDAP::Entry" ) ) {
my $entry = $oc[0];
@oc = $entry->get_value( "objectclass" )
or return;
}
in Schema.pm to
if ( ref($oc[0]) && UNIVERSAL::isa( $oc[0], "Net::LDAP::Entry" ) ) {
my $entry = $oc[0];
@oc = $entry->get_value( "objectclass" )
or return;
}
so that only hard references are checked by UNIVERSAL::isa().
I have updated the perl-ldap SVN accordingly.
Thanks for spotting the bug.
Peter
--
Peter Marschall
eMail: [EMAIL PROTECTED]