Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl `defined' and `undef' subroutine scope

Please take a look at the following code:

use strict;
use warnings;


print "subroutine is defined\n" if defined &myf;
myf();

sub myf
{
        print "called myf\n";
}

undef &myf;
#myf();
print "now subroutine is defined\n" if defined &myf;

The output is

subroutine is defined
called myf

The first print statement can print, does that mean the interpreter (or compiler?) looks further and sees the subroutine definition? If so, why it doesn't see the undef &myf; as the second print statement?

Thanks

like image 309
password636 Avatar asked Sep 20 '16 10:09

password636


People also ask

How to check if variable is undef in Perl?

Perl | defined() Function Defined() in Perl returns true if the provided variable 'VAR' has a value other than the undef value, or it checks the value of $_ if VAR is not specified. This can be used with many functions to detect for the failure of operation since they return undef if there was a problem.

What is undef in Perl?

undef is used for those variables which do not have any assigned value. One can compare it with NULL(in Java, PHP etc.) and Nil(in Ruby). So basically when the programmer will declare a scalar variable and don't assign a value to it then variable is supposed to be contain undef value.

What does {} mean in Perl?

{} , in this context, is the anonymous hash constructor. It creates a new hash, assigns the result of the expression inside the curlies to the hash, then returns a reference to that hash.


1 Answers

That doesn't have to do with scope, but with compile time and run time. Here's a simplified explanation.

The Perl interpreter will scan your code initially, and follow any use statements or BEGIN blocks. At that point, it sees all the subs, and notes them down in their respective packages. So now you have a &::myf in your symbol table.

When compile time has reached the end of the program, it will switch into run time.

At that point, it actually runs the code. Your first print statement is executed if &myf is defined. We know it is, because it got set at compile time. Perl then calls that function. All is well. Now you undef that entry in the symbol table. That occurs at run time, too.

After that, defined &myf returns false, so it doesn't print.

You even have the second call to myf() there in the code, but commented out. If you remove the comment, it will complain about Undefined subroutine &main::myf called. That's a good hint at what happened.

So in fact it doesn't look forward or backward in the code. It is already finished scanning the code at that time.


The different stages are explained in perlmod.

Note that there are not a lot of use cases for actually undefing a function. I don't see why you would remove it, unless you wanted to clean up your namespace manually.

like image 85
simbabque Avatar answered Sep 28 '22 19:09

simbabque