SwaJime has asked for the wisdom of the Perl Monks concerning the following question:

So I'm stepping through some code in a cpan module ...

I have undef for @_, so I'm expecting to execute line 148 next. However, the debugger puts me on line 145. Why did it go to 145 instead of 148? Why would undef be treated as a true value?

DB<13> n Net::DBus::RemoteService::get_object(/usr/lib/perl5/Net/DBus/RemoteSer +vice.pm:144): 144: if (@_) { DB<13> l 144==> if (@_) { 145: my $interface = shift; 146: return $self->{objects}->{$object_path}->as_interface($int +erface); 147 } else { 148: return $self->{objects}->{$object_path}; 149 } 150 } 151 152: 1; 153 DB<13> x @_ 0 undef DB<14> n Net::DBus::RemoteService::get_object(/usr/lib/perl5/Net/DBus/RemoteSer +vice.pm:145): 145: my $interface = shift; DB<14> n Net::DBus::RemoteService::get_object(/usr/lib/perl5/Net/DBus/RemoteSer +vice.pm:146): 146: return $self->{objects}->{$object_path}->as_interface($int +erface); DB<14> x $interface 0 undef

The method was invoked as $proxy = $service->get_object($self->{object_path}, $mdata->{interface}); and the innards of the function have shifted the parameters into variables. So @_ should have 0 elements, right?

Here is the whole method from /usr/lib/perl5/Net/DBus/RemoteService.pm
135 sub get_object { 136: my $self = shift; 137: my $object_path = shift; 138 139: unless (defined $self->{objects}->{$object_path}) { 140: $self->{objects}->{$object_path} = Net::DBus::RemoteObject +->new($self, 141 $object_path); 142 } 143 144: if (@_) { 145: my $interface = shift; 146==> return $self->{objects}->{$object_path}->as_interface($i +nterface); 147 } else { 148: return $self->{objects}->{$object_path}; 149 } 150 }
Update: I just realized that the 1st parameter is the added class object. DUH :-( So it's a three element array. Back to this in a few after I rerun the debugger.

Replies are listed 'Best First'.
Re: Two element array, shifted twice, is true?
by dave_the_m (Monsignor) on Aug 16, 2016 at 18:25 UTC
    DB<13> x @_ 0 undef

    This shows that the array contains 1 element, and that element happens to be undefined. So @a in scalar context returns 1, which is true.

    Presumably get_object() is being called with 3 arguments.

    Dave.

      Yes, I had forgotten that since it is a class method, the class object is passed in as the first parameter. So the two explicit parameters are actually the second and third elements of @_. My third element was undef, which is a problem elsewhere in my code.