在 perl 中调用子程序 plack return 没有
calling subroutines in perl plack return nothing
我是 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 :(
如果我修复 return
语句中字符串的引号(您缺少结束双引号),那么我会收到警告
Variable "$number" is not available at source_file.pl line 7.
原因是词法值 $app
和 $number
是在 运行 时定义的,而子例程 count_number
在编译期间定义得更早
解决方案是将 count_number
的定义推迟到 运行 时间,方法是将其设为 anonymous 子例程。调用 $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}'
]
];
有一个相关警告
Variable "$number" will not stay shared
具有类似的解决方案。您可以在
perldoc perldiag
。消息按字母顺序列出和描述
my
运算符有两个作用:
- 在编译时,它引入了一个标量变量。
- 在 运行 时,它为该变量创建一个新的标量对象。
本质上,这两个标量是不同的变量,尽管它们具有相同的名称。
sub name { ... }
运算符只有编译时作用。它在编译时将子例程分配给给定的名称。因此,当子程序被编译时,它看到的是原始编译时变量,而不是稍后创建的 运行 时间变量。
因此,您不应嵌套命名子程序。事实上,如果你 use warnings
你会收到一条警告:“变量“$number”将不会保持共享状态”。
您有两个选择:
您可以使用可以看到 运行time 变量的闭包。这使用匿名子程序:
...
my $number = 10;
my $count_number = sub {
$number += 10;
};
$count_number->();
...
或者,您将值作为显式参数传递给单独的子例程。是的,这确实让事情变得有点复杂,但它也让不同的事情分开。清晰的数据流是好的设计的一个特征。
我是 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 :(
如果我修复 return
语句中字符串的引号(您缺少结束双引号),那么我会收到警告
Variable "$number" is not available at source_file.pl line 7.
原因是词法值 $app
和 $number
是在 运行 时定义的,而子例程 count_number
在编译期间定义得更早
解决方案是将 count_number
的定义推迟到 运行 时间,方法是将其设为 anonymous 子例程。调用 $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}'
]
];
有一个相关警告
Variable "$number" will not stay shared
具有类似的解决方案。您可以在
perldoc perldiag
。消息按字母顺序列出和描述
my
运算符有两个作用:
- 在编译时,它引入了一个标量变量。
- 在 运行 时,它为该变量创建一个新的标量对象。
本质上,这两个标量是不同的变量,尽管它们具有相同的名称。
sub name { ... }
运算符只有编译时作用。它在编译时将子例程分配给给定的名称。因此,当子程序被编译时,它看到的是原始编译时变量,而不是稍后创建的 运行 时间变量。
因此,您不应嵌套命名子程序。事实上,如果你 use warnings
你会收到一条警告:“变量“$number”将不会保持共享状态”。
您有两个选择:
您可以使用可以看到 运行time 变量的闭包。这使用匿名子程序:
... my $number = 10; my $count_number = sub { $number += 10; }; $count_number->(); ...
或者,您将值作为显式参数传递给单独的子例程。是的,这确实让事情变得有点复杂,但它也让不同的事情分开。清晰的数据流是好的设计的一个特征。