gpt4 book ai didi

perl - 编写严格编译代码的最佳方法

转载 作者:行者123 更新时间:2023-12-02 08:58:11 26 4
gpt4 key购买 nike

检查提供给子例程的参数以进行严格编译的最佳方法是什么(我的解决方案有效,但有更好的方法?)

我有一个大型旧库,我想更正代码,以便我可以添加 use strict;对此,我的大多数错误都是这样的(在页面加载时会生成 189 个错误):

Use of uninitialized value in string eq at ../lib/cgilibtest.pl line 1510
Use of uninitialized value in concatenation (.) or string at ../lib/cgilibtest.pl line 1511.

它们是由如下编写的子例程生成的:

#!/usr/bin/perl -w
sub example()
{
my $var1 = shift @_;
my $var2 = shift @_;
my $var3 = shift @_;
if($var2 eq ""){var2 = "something";} # this line generates the first type of error beacause $var2 is not defined
return "var1 = ".$var1.", var2 = ".$var2.", var3 = ".$var3; # this line generates the second type of error, beacause $var3 is not defined
}
print "Content-type: text/html\n\n";
$someVar = &example("firstVar");
print $someVar;

我的解决方案是使用三元运算符并将它们写为:

#!/usr/bin/perl -w
use strict;

sub example()
{
my $var1 = ($_[0])?$_[0]:"";
my $var2 = ($_[1])?$_[1]:"something";
my $var3 = ($_[2])?$_[2]:"";
return "var1 = ".$var1.", var2 = ".$var2.", var3 = ".$var3;
}
print "Content-type: text/html\n\n";
my $someVar = &example("firstVar");
print $someVar;

在 PHP 中,我使用函数示例 ($var1, $var2 = null, $var3 = null){...}

附注如果有人知道关于“用 Perl 编写严格代码”的好教程或手册,请留下一个链接。

谢谢。

最佳答案

  • 我认为 PBP ( Perl Best Practices ) 是一本关于“严格”风格的好读物。如果如果你按照它所说的去做,你将至少编写符合严格警告的代码。

我看到的是 uninit 警告。并且,uninit 警告带有 warnings ,而不是严格。尽管它通常与严格齐头并进。

对于您的特定错误,重要的是要认识到,当您移动 arg 数组(我倾向于将其称为“甲板”)时,方法/函数的用户可能没有在该位置传递任何内容。因此这是一个很好的习语;

my $var1 = shift || '';

'' 尚未初始化,因此不会收到警告。三元数也是一种很好的方法,我在生产代码中充分使用了它们。

当然,还有另一个问题。如果你看一下上面的代码,我在期待什么?我预计 $var1 可能尚未传递任何数据。如果是这种情况,并且我仍然想将其字符串化 - 并且本地代码中有足够这样的情况 - 有时你只需这样做:

# don't bug me about uninitialized stringed values
# just concatenate them
no warnings 'uninitialized';
return "var1 = ".$var1.", var2 = ".$var2.", var3 = ".$var3;

这与使用一堆变量执行此操作等效的代码:

my $var = shift || '';

这个想法并不是对未初始化的数据感到惊讶——拥有适合实例的策略,而不是盲目地按照标准进行编码。

由于您的子程序足够简单,因此上面的代码将起作用。但您可能希望让它在未来做更多的事情,所以我建议使用以下构造来隔离我们可以接受未初始化值的部分以及您不想被捕获的部分。

{   no warnings 'uninitialized';
$string = ...;
}
$obj_that_should_be_defined->do_something_objecty( $string );

do block 对此也很有用。

$obj_that_should_be_defined->do_something_objecty( 
do { no warnings 'uninitialized'; sprintf( ... ); }
);

当然,作为变量传递的任何内容,您也可以使用map进行过滤。如果您只想处理 undef,则以下方法有效。

$object->method( map { defined() ? $_ : '' } @anon_args );  
  • 我要警告的是,任何尚未在范围内检查过的内容(来自其他地方的任何内容:参数、IO、正则表达式捕获、函数返回)都可能未初始化。良好的编码实践应该让您检查所有这些事情如果您在这种情况下关心它们是否undef

现在,很多时候人们检查 undefined variable 只是为了发牢骚。由于 Perl 的消息已经变得更好,也许它们将来可以改进。可能没有必要专门发出嘎嘎声。

my $feldman = Feldman->new( qw<here is some data for you> )
or die 'Could not create Feldman!'
;
$feldman->dont_just_sit_there_do_something();

但是,如果没有显式的or die,如果$feldman未定义,上面的代码肯定会死掉。您无法对未定义的值调用方法,因此存在不专门检查的情况。如果 $feldman 未定义,那么您没有创建它,您只需从未定义到错误消息进行多一层推断。两者都没有告诉我们为什么该对象没有被创建,只是它没有被创建。 (构造函数至少应该对它没有的东西吹毛求疵。)

关于perl - 编写严格编译代码的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3317548/

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