gpt4 book ai didi

Perl - 这是looks_like_number 的错误,还是我是个愚蠢的人?

转载 作者:行者123 更新时间:2023-12-04 22:47:33 26 4
gpt4 key购买 nike

这段代码:

#!/usr/bin/perl -w

use strict;
use Scalar::Util qw(looks_like_number);

sub what_the_fudge {
my $string = "foo 123 bar";
if ($string =~ /foo (.+) bar/) {
if (looks_like_number($1)) {
print "$1 looks like a number\n";
} else {
print "$1 doesnt look like a number\n";
}
}
}

&what_the_fudge;
&what_the_fudge;
&what_the_fudge;

显示这个:
123 doesnt look like a number
123 looks like a number
123 looks like a number

为什么它第一次无法将其识别为数字? =(
这让我很困惑。

关于我的环境的一些信息:

操作系统:OSX 10.6.8
perl -e 'use Scalar::Util; print "$Scalar::Util::VERSION\n"'--> 1.19
perl -v--> 这是 perl,v5.10.0 为 darwin-thread-multi-2level 构建(有 2 个注册补丁,更多细节见 perl -V)

最佳答案

我对你的程序做了一些修改:

#! /usr/bin/env perl
#
use strict;
use warnings;
use Scalar::Util qw(looks_like_number);

print "Scalar version: $Scalar::Util::VERSION\n";
what_the_fudge();
what_the_fudge();
what_the_fudge();

sub what_the_fudge {
my $string = "foo 123 bar";
if ($string =~ /foo (.+) bar/) {
if ( looks_like_number $1 ) {
print qq("$1" looks like a number\n);
} else {
print qq("$1" doesn't look like a number\n);
}
}
}

我有一台运行 10.8.6 的 Mac,我使用 Perlbrew 来测试 5.8.9、5.10、5.12 和 5.18。前两个我得到这个:
Scalar version: 1.19
"123" doesnt look like a number
"123" looks like a number
"123" looks like a number

对于其他两个版本,我得到了这个:
Scalar version: 1.22
"123" looks like a number
"123" looks like a number
"123" looks like a number

然后我对你的程序做了另一个轻微的改变。而不是简单地使用 $1 , 我设置 my $test = $1 ,然后跑 looks_like_number( $test ) ;

这样做之后,我得到了这个:
Scalar version: 1.19
"123" looks like a number
"123" looks like a number
"123" looks like a number

您必须了解的一件事是 $1 , $_ ,它们的同类不仅仅是全局变量,而且总是在 main 中。命名空间。这意味着如果您使用 $1 调用子程序,子程序最终可能会修改该值。

您应该始终分配自己的变量(最好是 my 变量),而不是依赖特殊的 Perl 变量。这意味着不使用 $_whilefor循环,而不是操作 @_直接在子程序中。并且,当您使用正则表达式捕获时,您应该将自己的变量分配给 $1 , $2等尽快。

顺便说一句,Scalar::Util 1.22 版和1.19 版之间最有趣的区别是1.22 版将使用C 编译代码(如果存在)。如果没有,它会加载 Perl 版本的 Scalar::Util::PP。但是,当我使用 Scalar::Util::PP 时在 Perl 5.12 和 5.18 中,我仍然得到正确的输出。

好奇者和好奇者

我尝试修改 Scalar::Util看看发生了什么。但是,我看到:
require List::Util; # List::Util loads the XS

Perl 版本的代码包含在一个大的 Eval 语句中。有趣的是,副作用只出现在第一个中——尽管子例程正在设置字符串,并运行正则表达式。相同的代码,但执行两种不同的方式。

$1 周围添加引号使其行为正确:
if ( looks_like_number "$1" ) {

也只需将其打印出来即可使其工作:
print "The value is " . $1 . "\n";
if ( looks_like_number $1 ) {

或者将其分配给另一个变量,但不使用该变量:
my $test = $1;
if ( looks_like_number $1 ) { works now...

让我们使用调试器,看看我们是否可以跟踪问题:
$ perl -d test.pl

Loading DB routines from perl5db.pl version 1.31
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(test.pl:7): print "Version of Scalar::Util: $Scalar::Util::VERSION\n";
DB<1> c
Version of Scalar::Util: 1.19
"123" looks like a number.
"123" looks like a number.
"123" looks like a number.
Debugged program terminated. Use q to quit or R to restart,
use o inhibit_exit to avoid stopping after program termination,
h q, h R or h o to get additional info.

有用?让我们在没有 -d 的情况下尝试相同的命令范围:
$ perl test.pl
Version of Scalar::Util: 1.19
"123" doesn't look like a number.
"123" looks like a number.
"123" looks like a number.

如果您无法在调试器中看到它,您如何追踪这个问题?

关于Perl - 这是looks_like_number 的错误,还是我是个愚蠢的人?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18198558/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com