如果你必须为防御性编码选择你最喜欢的(聪明的)技术,它们会是什么?虽然我目前的语言是Java和Objective-C(有C++背景),但可以随意用任何语言回答.这里的重点是巧妙的防御技术,而不是我们这里70%以上的人已经知道的那些.所以现在是时候深入挖掘你的技巧了.
换句话说,试着想到除了这个无趣的例子之外:
if(5 == x) 而不是 if(x == 5):避免意外的分配以下是一些有趣的最佳防御性编程实践的示例(特定于语言的示例在Java中):
- 锁定变量,直到您知道需要更改它们
也就是说,您可以声明所有变量,final直到您知道需要更改它为止,此时您可以删除final.一个常见的未知事实是这对方法参数也有效:
public void foo(final int arg) { /* Stuff Here */ }
Run Code Online (Sandbox Code Playgroud)
- 当发生不好的事情时,留下一丝证据
当你遇到异常时,你可以做很多事情:显然,记录它并执行一些清理会有一些.但是你也可以留下一些证据(比如将变量设置为"UNABLE TO LOAD FILE"等哨兵值,或者99999在调试器中有用,以防你碰巧超过异常catch块).
- 谈到一致性:魔鬼在细节中
与您正在使用的其他库一致.例如,在Java中,如果要创建一个提取一系列值的方法,则使下限包含且上限为exclusive.这将使其与String.substring(start, end)以相同方式操作的方法一致.您将在Sun JDK中找到所有这些类型的方法,因为它使各种操作包括元素的迭代与数组一致,其中索引从零(包括)到数组的长度(独占).
那么你最喜欢的防守做法是什么?
更新:如果您还没有,请随意加入.在选择正式答案之前,我有机会获得更多回复.
可能重复: 如何将一个数组和一个字符串作为参数传递给函数?
我有一个函数或子例程,它将第一个参数作为数组,第二个参数作为标量.例如,
sub calc {
my @array = $_[0];
my $scalar = $_[1];
print @array, $scalar;
}
Run Code Online (Sandbox Code Playgroud)
问题是该函数使数组等于传入的数组的第一个值,并且标量是传入的数组的第二个值.当我想要第一个数组是整个数组时,我不知道需要制作数组的深层副本.例如,
my @array = ('51', 'M');
my $scalar = 21;
Run Code Online (Sandbox Code Playgroud)
和
calc(@array, $scalar)
Run Code Online (Sandbox Code Playgroud)
会51 M在我想要的时候打印51 M 21.
我在perl中有一个函数
sub create_hash()
{
my @files = @_;
foreach(@files){
if(/.text/)
{
open($files_list{$_},">>$_") || die("This file will not open!");
}
}
}
Run Code Online (Sandbox Code Playgroud)
我通过传递如下所示的数组参数来调用此函数:
create_hash( @files2);
Run Code Online (Sandbox Code Playgroud)
该数组中有大约38个值.但我收到编译错误:
Too many arguments for main::create_hash at ....
Run Code Online (Sandbox Code Playgroud)
我在这里做错了什么?
我的perl版本是:
This is perl, v5.8.4 built for i86pc-solaris-64int
(with 36 registered patches, see perl -V for more detail)
Run Code Online (Sandbox Code Playgroud) 我正在学习perl并且理解使用shift解包子例程参数是一种常见且公认的做法.我也理解省略函数参数以使用默认@_数组是常见且可接受的做法.
考虑到这两件事,如果你调用一个没有参数的子程序,就@_可以改变can(并且如果使用shift).这是否意味着使用默认参数调用另一个子例程,或者事实上,@_在此之后使用数组,这被认为是不好的做法?考虑这个例子:
sub total { # calculate sum of all arguments
my $running_sum;
# take arguments one by one and sum them together
while (@_) {
$running_sum += shift;
}
$running_sum;
}
sub avg { calculate the mean of given arguments
if (@_ == 0) { return }
my $sum = &total; # gets the correct answer, but changes @_
$sum / @_ # causes division by zero, since @_ is now empty
} …Run Code Online (Sandbox Code Playgroud) 我想将一些参数(其中一个是可选的)传递给一个函数.我知道的唯一方法是使用列表(@)作为参数.因此,它没有内容或1个元素(永远不会是undef),所以我可以使用以下代码:
sub someFunction($$@) {
my ( $oblig_param1, $oblig_param2, $option_param ) = @_;
...
}
Run Code Online (Sandbox Code Playgroud)
这段代码有效,但我觉得这可能不是最好的解决方法.
有没有其他方法可以做到这一点?
谢谢.
在我的代码中,我一直在使用函数调用中相当原始的提取参数方法,如下所示:
sub addSix ($$$$$$) {
my ($a, $b, $c, $d, $e, $f) = (shift, shift, shift, shift, shift, shift);
return $a + $b + $c + $d + $e + $f;
}
print addSix (1, 2, 3, 4, 5, 6) . "\n";
Run Code Online (Sandbox Code Playgroud)
(忘记原始代码,突出位是多次shift调用).
现在这对我来说似乎相当混乱,虽然Perl可能有类似的东西:
my ($a, $b, $c, $d, $e, $f) = shift (6);
Run Code Online (Sandbox Code Playgroud)
或类似的东西.
但我找不到那样的东西.我知道我可以使用数组,但我想我仍然需要将数组解压缩到单个标量中.对于上面的示例情况来说这不会太糟糕,其中六个参数相似,但我对它们不适合作为数组的情况更感兴趣.
如何在不结束shift关键词的情况下提取参数?
我们都应该熟悉Perl中与原型相关的问题.以下是两个大佬:
第二项是我现在很好奇的一项.
我知道有两种方法可以在调用子程序时颠覆/解决/忽略原型强制执行:
Foo->subroutine_name();&印记调用潜艇.&subroutine_name();还有其他有趣的案例我错过了吗?
UDPATE:
@brian d foy,我并不特别想逃避原型,但我想知道"有多少种方法可以做到这一点?" 出于好奇,我问这个问题.
@jrockway,我同意你的观点,我相信你有更明确,更简洁地描述了关于原型问题的第一点,人们会误解它们.也许问题在于程序员的期望,而不在于功能.但这确实是一个我不想要的哲学问题.
我在使用Perl grep()时遇到麻烦,该字符串可能包含被解释为正则表达式量词的字符.
当grep模式为"g ++"时,我得到以下错误,因为'+'符号被解释为量词.以下是程序的输出:
1..3
ok 1 - grep, pattern not found
ok 2 - grep, pattern found
Nested quantifiers in regex; marked by <-- HERE
in m/g++ <-- HERE / at escape_regexp_quantifier.pl line 8.
Run Code Online (Sandbox Code Playgroud)
是否有一个修饰符我可以用来表示grep应该忽略量词,还是有一个函数可以逃避量词?
#! /usr/bin/perl
sub test_grep($)
{
my $filter = shift;
my @output = ("-r-xr-xr-x 3 root bin 122260 Jan 23 2005 gcc",
"-r-xr-xr-x 4 root bin 124844 Jan 23 2005 g++");
return grep (!/$filter/, @output);
}
use Test::Simple tests => 2;
ok(test_grep("foo"), "grep, …Run Code Online (Sandbox Code Playgroud) 所以我需要的是一个简单的方法来判断两个数组在perl中是否相同.订单没关系,所以我正在寻找这样的东西:
my @a = (1, 2, 3);
my @b = (2, 3, 1);
my @c = (1, 2, 4);
&identical(@a, @b) 返回1
&identical(@a, @c) 返回0
谢谢!
这是一个简短的测试程序:
sub foo($;@) {
my $sql = shift;
my @params = @_;
print "sql: $sql\n";
print "params: " . join(",", @params);
}
sub bar($;@) {
foo(@_);
}
bar("select * from blah where x = ? and y = ?",2,3);
print "\n";
Run Code Online (Sandbox Code Playgroud)
为什么输出如下:
sql: 3
params:
Run Code Online (Sandbox Code Playgroud)
而不是这个?
sql: select * from blah where x = ? and y = ?
params: 2,3
Run Code Online (Sandbox Code Playgroud)