在perl plack中调用子例程不会返回任何结果
我是perl-plack/psgi新手。我想访问perl-plack/psgi循环中的一个子例程,但看起来好像该子例程没有被执行。每个父变量(如$number)都应该像编写常规perl脚本时一样自动传递。我会错过什么吗,可能吗在perl plack中调用子例程不会返回任何结果,perl,subroutine,plack,psgi,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-Ty
..
my $app = sub {
my $number = 10;
&count_number;
sub count_number {
$number +=10;
}
return ['200',[ 'Content-Type' => 'application/json' ],
[ "{\"number\":$number} ]];
}
..
返回的是10而不是20:(如果我在
return
语句中修复了字符串上的引号(您缺少一个结束双引号),那么我会收到警告
变量“$number”在source_file.pl第7行不可用
原因是词法值$app
和$number
是在运行时定义的,而子例程count\u number
是在编译过程中更早定义的
解决方案是将count\u number
的定义推迟到运行时,将其改为匿名子例程。调用$count\u 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->();
输出
有一个相关的警告
变量“$number”将不会保持共享状态
使用类似的解决方案。您可以在
。消息按字母顺序列出和描述,
my
运算符具有两种效果:
- 在编译时,它引入了标量变量
- 在运行时,它会为该变量创建一个新的标量对象
sub-name{…}
运算符仅具有编译时效果。它在编译时将子例程分配给给定的名称。因此,当编译sub时,它看到的是原始编译时变量,而不是稍后创建的运行时变量
因此,您不应该嵌套命名的sub。事实上,如果您使用warnings
,您将收到一条关于此的警告:“变量“$number”将不会保持共享”
您有两个选择:
- 可以使用查看运行时变量的闭包。这将使用匿名子例程:
... my $number = 10; my $count_number = sub { $number += 10; }; $count_number->(); ...
- 或者,将值作为显式参数传递给一个单独的子例程。是的,这会使事情变得复杂一些,但它也会使单独的事情保持分离。清晰的数据流是良好设计的一个特征
sub
声明嵌套在另一个sub
声明中,这通常是错误的。此外,my$number
在sub
声明中声明,因此每次执行完sub
后它都会消失。但更重要的是:您想要计算什么?它是全局计数器、每个会话的值等吗?还有,它是如何计算的您正在运行应用程序吗?如果服务器正在运行应用程序的多个副本(例如线程/分叉),并且您希望计数器是全局的,则需要以不同的方式实现(例如数据库或其他全局存储)。谢谢。我是否必须传递变量,例如$number=&count\u number(%args)-这会使事情复杂化。昨天我已经考虑过多处理环境,也包括负载平衡器。什么是好的内部(只有一个外部用户cookie,比如会话id)针对多线程和服务器的存储解决方案?我想在这一点上我只能说:这取决于您需要什么,您还没有完全描述。我使用过,也听说过+。Mojolicous支持..@hauk:通常,$number
可以通过Perl的引用计数工作方式防止消失。即使在子例程$app
退出后,$number
仍然有一个来自count\u number
的引用,因此它没有被删除。这在这里不起作用,因为子例程count\u number
是在编译时创建的,而没有$number
变量可引用。@Borodin是的,这是一点,谢谢如果Plack应用程序是在多线程或分叉服务器上运行的,尽管这些都不能真正帮助OP:-)非常感谢清晰的数据流。当代码中有10次相同的代码片段时,为了更新部分代码,只使用一次会更容易。我现在就试试你的代码。
...
my $number = 10;
my $count_number = sub {
$number += 10;
};
$count_number->();
...