📜  珀尔 |子程序的范围

📅  最后修改于: 2022-05-13 01:54:50.088000             🧑  作者: Mango

珀尔 |子程序的范围

Perl 中的子程序可重用的代码单元。这是一个动态的概念。函数和子例程是可以互换使用的两个术语。如果你想严格语义,接受参数和返回值的小块命名代码块称为子例程。 Perl 中的内置子例程通常被称为 Perl 的函数,因为它们提供了额外的功能。作为类定义的一部分创建的子例程称为方法
几乎可以从任何地方调用子例程,并在它们完成执行时将控制权返回到调用点。它们可以用零个或多个参数调用,并且可能返回零个或多个结果

像变量一样,子程序既可以只声明(不定义它们所做的工作),也可以声明和定义。为了简单地声明一个子例程,我们使用以下形式之一:

其中SUB_NAME是正在创建的子例程的名称, PROTOTYPE是子例程在调用时应该期望的参数的原型, ATTRIBUTES是子例程展示的属性列表。 PROTOTYPEATTRIBUTES参数是可选的。

注意:子例程可以命名或匿名。 Perl 允许创建匿名子程序,也就是没有名字的子程序。这可以通过省略NAME组件来完成。但是,您不能在没有定义的情况下创建匿名子例程(Perl 无法在不知道子例程名称的情况下稍后附加定义)。您还需要将子例程分配给一个标量变量,以便以后调用它。

例子:

# Perl program to demonstrate
# simple subroutine
  
sub message    # Declared subroutine 
{ 
    print "Hello!\n";   # Body of subroutine
}
  
$message = message;    # Calling subroutine
输出:
Hello!

子程序范围

范围的概念涉及定义变量或子例程的区域,并且可以由程序的其他部分使用和访问。 Perl 子例程主要支持两种类型的作用域——词法全局

就像变量一样,子例程也存在于特定的范围内,无论是词法范围还是全局范围。

全球范围如果子例程和变量可以在整个程序的任何地方使用,则它是全局范围的,除非分别被同名的词法范围的子例程和变量覆盖。全局变量可用于程序的所有不同函数和库,尽管它们需要在单独用于每个函数之前加载。

这些子例程只能访问全局范围的变量。 Perl 中的大多数内置函数都是全局作用域的。

例子

#!/usr/bin/perl
  
# Subroutine definition
sub Max 
{
      
    # get total number of arguments passed.
    $n = scalar(@_);     # local scoped 
    $max = 0;             # local scoped
      
    foreach $item (@_) 
    {
        if ($item > $max)
        {
            $max = $item;
        }
    }
    print "Max from the given numbers : $max\n";
}
  
# Subroutine call
Max(10, 20, 30, 40, 50, 100); # called globally
  
$user_input = "GeeksforGeeks";
if (length($user_input) >= 7)
{
    Max(45, 56, 78, 76, 26, 90);     # called locally
}
输出:
Max from the given numbers : 100
Max from the given numbers : 90

词法作用域子例程也可以像变量一样是词法的。词法子程序是在函数或 If-Else 条件中声明和定义的子程序,并且只能在该范围内操作。在范围之外,它们不会被程序的其他部分识别。词法子例程可以访问全局变量和局部变量(在其范围内定义)。词法子程序的调用与普通子程序一样:

对 sub1 的第一次调用很好,但第二次将是编译时错误,因为 sub1 已在其定义范围之外被调用。

例子:

#!/usr/bin/perl
  
$user_input = "Geeks";
  
if (length($user_input) >= 7) 
{
    # Subroutine definition local to IF block
    sub Max 
    {
          
        # get total number of arguments passed.
        $n = scalar(@_);     # local scoped 
        $max = 0;             # local scoped
          
        foreach $item (@_) 
        {
            if ($item > $max) 
            {
                $max = $item;
            }
        }
        print "Max from the given numbers : $max\n";
    }
  
    Max(45, 56, 78, 76, 26, 90);     #called locally
}
else 
{
  
    # Subroutine definition local to ELSE block
    sub Max 
    {
          
        # get total number of arguments passed.
        $n = scalar(@_);     # local scoped 
        $max = 0;             # local scoped
          
        foreach $item (@_) 
        {
            if ($item > $max) 
            {
                $max = $item;
            }
        }
        print "Max from the given numbers : $max\n";
    }
  
    Max(4, 6, 17, 37, 6, 9);     #called locally
}
输出:
Max from the given numbers : 37

使用mylocal

Perl 子程序中的mylocal用于限制程序中变量或子程序的范围。限制范围意味着限制可以访问各个变量的区域。 my的影响Perl 中的所有变量默认都是全局变量,这意味着编译器可以从程序中的任何位置访问它们。但是也可以使用my 运算符创建称为词法变量的私有变量。
my关键字声明了一个在当前块中作用域的变量。在块的持续时间内,新变量将优先于任何先前作用域的变量。当块结束时,变量超出范围。

例子

#!/usr/bin/perl
  
my $string = "GeeksforGeeks";
print "$string\n";
myfunction();   # function call
print "$string\n";
  
# Subroutine 1 definition
sub myfunction 
{
      
    # Private variable for function
    my $string = "GFG";
    print "Inside myfunction $string\n";
    mysub();
}
  
# Subroutine 2 definition
sub mysub
{
    print "Inside mysub $string\n";
}
输出:
GeeksforGeeks
Inside myfunction GFG
Inside mysub GeeksforGeeks
GeeksforGeeks

块终止的那一刻,变量实际上从视图中消失了。我们不能从定义它的块外部访问用my声明的变量。
这也意味着在模块中用my声明的变量在该模块之外是不可访问的(因为该模块是单个块),即使使用$MyModule::string显式调用也是如此。


local的影响local变量实际上是一个动态范围的变量。它有效地在当前范围内创建全局变量的副本。它的操作就像一个词法范围的变量;当变量超出当前范围时,其效果消失,变量返回其原始值而不是简单地消失。

例子:

#!/usr/bin/perl
  
$string = "GeeksforGeeks";
print "$string\n";
myfunction();
print "$string\n";
  
# Subroutine 1 definition
sub myfunction 
{
      
    # Private variable for function
    local $string = "GFG";
    print "Inside myfunction $string\n";
    mysub();
}
  
# Subroutine 2 definition
sub mysub
{
    print "Inside mysub $string\n";
}
输出:
GeeksforGeeks
Inside myfunction GFG
Inside mysub GFG
GeeksforGeeks

注意:使用local修改的变量的值对于从已本地化变量的块调用的所有函数都是一致的。

因此, local只是挂起全局变量并为全局变量创建一个临时范围,而my在它定义的范围内定义了一个新的词法变量,一旦我们超出其定义的范围,这个变量就会被销毁。 our影响Perl 支持另一个范围声明,它使我们能够使用关键字our来创建选择性的全局变量。 our声明是一项相对较新的发明,它允许您将变量声明为全局变量,并且可能被脚本中定义的任何其他子例程使用。
myour都是词法作用域变量的例子。唯一的区别在于词法作用域的应用级别。

例子:

#!/usr/bin/perl
  
our $string = "GeeksforGeeks";
print "$string\n";
myfunction();
print "$string\n";
  
# Subroutine definition
sub myfunction 
{
      
    # Private variable for function
    our $string = "GFG";
    print "Inside myfunction $string\n";
}
输出:
GeeksforGeeks
Inside myfunction GFG
GFG

在同一个变量上使用our的函数内,或者任何块内的任何形式的嵌套都没有效果。它总是引用同一个全局变量。在使用my声明的变量上使用our将无效。