我尝试使用Perl 的给定 / when 构造作为子例程中的表达式,它在某些情况下应该返回一个包含一些警告的字符串,否则返回一个空字符串:
sub warn_about_invalid_date {
my ( $date ) = @_;
return do {
given ($date) { # <------------ works only with given, does not with for
when (not /^\d{4}-\d{2}-\d{2}$/) {
'Invalid date format (should be YYYY-MM-DD)';
}
when ('0001-01-01') {
'Use of default date "0001-01-01"';
}
when ($_ lt '1900-01-01') {
'Probably too far in the past (year < 1900)';
}
when ($_ gt '2100-01-01') {
'Probably too far in the future (year > 2100)';
}
default {
'';
}
}
};
}
return do { }
(请忽略每个表达式末尾的一些冗余/冗长/非惯用的 Perl 代码或分号,这些是我公司的编码实践。)
但是,因为我尝试遵循 Perl 的良好实践,以及来自 brian d foy 的Effective Perl的这些,这里使用 for() 而不是 given(),所以我在上面的代码段中交换given
了for
......它没有作为我期望。任何输入的返回值总是''
(空字符串/假)。
我已将问题缩小到这种情况:
use v5.10.1;
use strict;
use warnings;
use Data::Dumper;
sub test_for {
for (shift) {
when (1) { 'True' }
default { 'False' }
}
}
sub test_given {
given (shift) {
when (1) { 'True' }
default { 'False' }
}
}
sub test_if {
if (shift) { 'True' }
else { 'False' }
}
sub test_given_if {
given (shift) {
if ($_) { 'True' }
else { 'False' }
}
}
sub test_for_if {
for (shift) {
if ($_) { 'True' }
else { 'False' }
}
}
$Data::Dumper::Indent = 0;
$Data::Dumper::Terse = 1;
say "test_for( $_ ): ", Dumper test_for($_) for 0..1;
say "test_given( $_ ): ", Dumper test_given($_) for 0..1;
say "test_if( $_ ): ", Dumper test_if($_) for 0..1;
say "test_for_if( $_ ): ", Dumper test_for_if($_) for 0..1;
say "test_given_if( $_ ): ", Dumper test_given_if($_) for 0..1;
哪个输出
perl-5.10.1
==========
Useless use of a constant in void context at /home/grozn/test3a.pl line 9.
Useless use of a constant in void context at /home/grozn/test3a.pl line 16.
Useless use of a constant in void context at /home/grozn/test3a.pl line 35.
Useless use of a constant in void context at /home/grozn/test3a.pl line 36.
Useless use of a constant in void context at /home/grozn/test3a.pl line 42.
test_for( 0 ): ''
test_for( 1 ): ''
test_given( 0 ):
test_given( 1 ):
test_if( 0 ): 'False'
test_if( 1 ): 'True'
test_for_if( 0 ): ''
test_for_if( 1 ): ''
test_given_if( 0 ):
test_given_if( 1 ):
test_for_constant( 0 ): ''
test_for_constant( 1 ): ''
perl-5.16
==========
Useless use of a constant ("True") in void context at /home/grozn/test3a.pl line 35.
Useless use of a constant ("False") in void context at /home/grozn/test3a.pl line 36.
Useless use of a constant ("Foo") in void context at /home/grozn/test3a.pl line 42.
test_for( 0 ): ''
test_for( 1 ): ''
test_given( 0 ): 'False'
test_given( 1 ): 'True'
test_if( 0 ): 'False'
test_if( 1 ): 'True'
test_for_if( 0 ): ''
test_for_if( 1 ): ''
test_given_if( 0 ): 'False'
test_given_if( 1 ): 'True'
test_for_constant( 0 ): ''
test_for_constant( 1 ): ''
perl-5.18
==========
when is experimental at /home/grozn/test3a.pl line 9.
given is experimental at /home/grozn/test3a.pl line 15.
when is experimental at /home/grozn/test3a.pl line 16.
given is experimental at /home/grozn/test3a.pl line 27.
Useless use of a constant ("True") in void context at /home/grozn/test3a.pl line 35.
Useless use of a constant ("False") in void context at /home/grozn/test3a.pl line 36.
Useless use of a constant ("Foo") in void context at /home/grozn/test3a.pl line 42.
test_for( 0 ): ''
test_for( 1 ): ''
test_given( 0 ): 'False'
test_given( 1 ): 'True'
test_if( 0 ): 'False'
test_if( 1 ): 'True'
test_for_if( 0 ): ''
test_for_if( 1 ): ''
test_given_if( 0 ): 'False'
test_given_if( 1 ): 'True'
test_for_constant( 0 ): ''
test_for_constant( 1 ): ''
test_for_if
从 perls 5.10.1、5.16.3 和 5.18.1 执行时(警告指向) 。
我的问题是:
这是for
/when
表达的正确行为吗?它并没有这样隐含地记录(Given / when 的“返回值”小节在“Experimental Details on given and when”部分中,并且仅提及),但据我所知for
,它是given
(for
应该和given
这里一样好的外用剂,不应该吗?)。
如果这是一个正确的行为,那么是否有任何理由使用for
而不是在修复如何对待given
的 Perl 5.18 中使用?或者我应该在 Perl 的文档中填写错误/发送拉取请求?given
$_
如果它坏了,我是否应该在 Perl 中填充一个错误(我的意思是我应该始终将for
其视为given
更全面的孪生兄弟)?
编辑:
我在choroba 的回答和评论if
之后添加了三个案例,其中他认为行为与and company相同。在那之后我变得更加困惑。for
if