在perl plack中调用子程序什么都不返回

时间:2018-04-29 11:19:23

标签: perl subroutine plack psgi

我是perl plack / psgi的新手。我想访问perl plack / psgi循环中的子程序,但看起来好像子程序没有被执行。像$ number这样的每个父变量都应该像编写常规perl脚本一样自动传递。我在这里想念一下,这可能吗?

..
my $app = sub {

  my $number = 10;

  &count_number;
  sub count_number {
    $number +=10;
  }


  return ['200',[  'Content-Type' => 'application/json' ],
  [ "{\"number\":$number} ]];     

}
.. 

返回10而不是20 :(

2 个答案:

答案 0 :(得分:1)

如果我在return语句中修改字符串上的引号(你缺少一个结束双引号),那么我会收到警告

  

变量“$ number”在source_file.pl第7行不可用。

原因是词汇值$app$number是在运行时定义的,而子例程count_number是在编译期间更早定义的

解决方案是通过将count_number定义为匿名子例程来将$count_number->()的定义推迟到运行时间。在定义

之后,还需要将调用my $app = sub { my $number = 10; my $count_number = sub { $number +=10; }; $count_number->(); return [ '200', [ 'Content-Type' => 'application/json' ], [ "{\"number\":$number}" ] ]; }; use Data::Dumper; print Dumper $app->(); 移动到
$VAR1 = [
            '200',
            [
                'Content-Type',
                'application/json'
            ],
            [
                '{"number":20}'
            ]
        ];

输出

scrollingDiv.scrollTop = element.offsetTop;

有相关警告

  

变量“$ number”不会保持共享

使用类似的解决方案。你可以在里面读到这两个 perldoc perldiag。消息按字母顺序列出并描述

答案 1 :(得分:0)

my运算符有两个效果:

  • 在编译时,它引入了一个标量变量。
  • 在运行时,它为该变量创建一个新的标量对象。

基本上,这两个标量是不同的变量,尽管它们具有相同的名称。

sub name { ... }运算符只有编译时效果。它在编译时将子例程分配给给定的名称。因此,当编译sub时,它会看到原始的编译时变量,而不是稍后创建的运行时变量。

因此,您不应该嵌套命名的subs。事实上,如果你use warnings收到警告:“变量”$ number“将不会保持共享状态。”

您有两种选择:

  • 您可以使用看到运行时变量的闭包。这使用匿名子程序:

    ...
    my $number = 10;
    my $count_number = sub {
      $number += 10;
    };
    
    $count_number->();
    
    ...
    
  • 或者,将值作为显式参数传递给单独的子例程。是的,这确实使事情变得复杂,但它也将单独的事物分开。清晰的数据流是良好设计的特征。