尽管检查了 undef,但仍警告未初始化的变量
Warning about uninitailized variable despite check for undef
我今天好像很傻,或者我有一个很奇怪的问题。请考虑以下代码:
#!/usr/bin/perl
use strict;
use warnings;
use warnings::unused;
use warnings FATAL => 'uninitialized';
my ($String, $Pattern);
$Pattern = "pattern";
$String = "pattern\n";
if (($String =~ m/^([^\ ]+).*$/s) &&
defined() &&
( =~ m/^.*$Pattern$/s)) {
print ."\n";
}
此代码产生以下警告(然后由于 use warnings FATAL => 'uninitialized';
而停止):
Use of uninitialized value in concatenation (.) or string at [...]
我真的不明白这一点,因为我正在测试 </code> 在使用它之前是否被定义(初始化)。罪魁祸首似乎是最后一条条件线(即 <code>( =~ m/^.*$Pattern$/s)
)。如果我离开这个,警告就消失了。
但是为什么呢?根据我的理解,该行应该只是 test </code>,但不会改变它的值(<code>$Pattern
并且 RegEx 的其余部分不包含括号,所以</code> 不应重新分配可能的匹配项)。</p>
<p>Hmmm ...在考虑时,我想到 Perl 可能会在正则表达式匹配时将 <code>
及其同事设置为 every 情况, RegEx 中是否有括号。这可以解释这种行为。是真的吗?
Contains the subpattern from the corresponding set of capturing parentheses from the last successful pattern match, not counting patterns matched in nested blocks that have been exited already.
由于第二个匹配是最后一个成功的模式匹配,在 if 块中 </code> 是 undef。</p>
<p>你可以这样做:</p>
<pre><code>my ($match) = ($String =~ m/^([^\ ]+).*$/s);
if (defined $match && $match =~ m/^.*$Pattern$/s) {
print $match."\n";
}
我正在根据上面的评论创建一个答案:
if (($String =~ m/^([^\ ]+).*$/s) && # If matching, this will set
defined() && # Here is still defined
( =~ m/^.*$Pattern$/s) # If matching, will reset all , .. vars
) {
因此,只要正则表达式匹配,它就会重置所有数字变量(以及其他与正则表达式相关的变量)。
我看到的唯一解决方案是拆分条件并将 </code> 保存在一个额外的变量中。无论如何,这通常是一件好事。</p>
<pre><code>if ($String =~ m/^([^\ ]+).*$/s and defined ) {
my $match = ;
if ($match =~ m/^.*$Pattern$/s) { ... }
}
请注意,在这种情况下,您甚至不必检查 defined
,因为如果此模式匹配,将始终定义 </code>。这取决于模式。</p>
<p><a href="https://perldoc.perl.org/perlvar.html" rel="nofollow noreferrer">perldoc perlvar</a>:</p>
<pre><code>$<digits> (, , ...)
Contains the subpattern from the corresponding set of capturing
parentheses from the last successful pattern match [...]
如果您不知道复杂语句的作用,请将其分成几部分。
if( $String =~ m/^([^\ ]+).*$/s ){
if( defined() ){
if( =~ m/^.*$Pattern$/s ){
我今天好像很傻,或者我有一个很奇怪的问题。请考虑以下代码:
#!/usr/bin/perl
use strict;
use warnings;
use warnings::unused;
use warnings FATAL => 'uninitialized';
my ($String, $Pattern);
$Pattern = "pattern";
$String = "pattern\n";
if (($String =~ m/^([^\ ]+).*$/s) &&
defined() &&
( =~ m/^.*$Pattern$/s)) {
print ."\n";
}
此代码产生以下警告(然后由于 use warnings FATAL => 'uninitialized';
而停止):
Use of uninitialized value in concatenation (.) or string at [...]
我真的不明白这一点,因为我正在测试 </code> 在使用它之前是否被定义(初始化)。罪魁祸首似乎是最后一条条件线(即 <code>( =~ m/^.*$Pattern$/s)
)。如果我离开这个,警告就消失了。
但是为什么呢?根据我的理解,该行应该只是 test </code>,但不会改变它的值(<code>$Pattern
并且 RegEx 的其余部分不包含括号,所以</code> 不应重新分配可能的匹配项)。</p>
<p>Hmmm ...在考虑时,我想到 Perl 可能会在正则表达式匹配时将 <code>
及其同事设置为 every 情况, RegEx 中是否有括号。这可以解释这种行为。是真的吗?
Contains the subpattern from the corresponding set of capturing parentheses from the last successful pattern match, not counting patterns matched in nested blocks that have been exited already.
由于第二个匹配是最后一个成功的模式匹配,在 if 块中 </code> 是 undef。</p>
<p>你可以这样做:</p>
<pre><code>my ($match) = ($String =~ m/^([^\ ]+).*$/s);
if (defined $match && $match =~ m/^.*$Pattern$/s) {
print $match."\n";
}
我正在根据上面的评论创建一个答案:
if (($String =~ m/^([^\ ]+).*$/s) && # If matching, this will set
defined() && # Here is still defined
( =~ m/^.*$Pattern$/s) # If matching, will reset all , .. vars
) {
因此,只要正则表达式匹配,它就会重置所有数字变量(以及其他与正则表达式相关的变量)。
我看到的唯一解决方案是拆分条件并将 </code> 保存在一个额外的变量中。无论如何,这通常是一件好事。</p>
<pre><code>if ($String =~ m/^([^\ ]+).*$/s and defined ) {
my $match = ;
if ($match =~ m/^.*$Pattern$/s) { ... }
}
请注意,在这种情况下,您甚至不必检查 defined
,因为如果此模式匹配,将始终定义 </code>。这取决于模式。</p>
<p><a href="https://perldoc.perl.org/perlvar.html" rel="nofollow noreferrer">perldoc perlvar</a>:</p>
<pre><code>$<digits> (, , ...)
Contains the subpattern from the corresponding set of capturing
parentheses from the last successful pattern match [...]
如果您不知道复杂语句的作用,请将其分成几部分。
if( $String =~ m/^([^\ ]+).*$/s ){
if( defined() ){
if( =~ m/^.*$Pattern$/s ){