Chinaunix首页 | 论坛 | 博客
  • 博客访问: 469974
  • 博文数量: 142
  • 博客积分: 4126
  • 博客等级: 上校
  • 技术积分: 1545
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-22 10:03
文章分类

全部博文(142)

文章存档

2011年(8)

2010年(7)

2009年(64)

2008年(63)

我的朋友

分类:

2008-12-09 17:28:47

1.1.1 提出问题
 
你想要在一个标量还没有值的时候,给它提供一个默认值。这经常发生在你想要一个硬编码的默认值,为一个运行时被命令行或环境变量所覆盖的变量。
 
1.1.2 解决方案
 
使用 || 或 ||=操作符,在字符和数字模式下都可以工作。
 

# 如果$b为真,则$a等于$b,否则等于$c

$a = $b || $c;

# 如果$x不是真就把$x设成$y

$x ||= $y;
# 如果你的变量的有效值是 0, "0", 和 "" , 则使用:


# 如果$b是被定义过的则使用$b , 否则使用$c

$a = defined($b) ? $b : $c;

# 将来perl中新的操作符

use v5.9;
$a = $b // $c;

1.1.2 讨论

这两个方法(defined 和 ||)最大的区别是他们检测什么:defined检测相对真实。0,"0"和""这三个值在perl中默认是假值。如果你的变量已经存储量他们当中的一个,比且你希望保持这个值,那么||就无法工作了。你必须使用defined形式的更加复杂的三元测试。这对于安排你的程序是关心真或假值,还是关心值被定义和未定义,经常是很合适的。
 相对于其他语言中返回值被限定只可以是1或者0,perl的||操作符有更多有趣的特性:如果第一个操作数是真的话,它返回它的第一个操作数,否则它返回第二个操作数。&&操作符还可以返回最后一个被计算到的表达式,但是这个特性很少使用。这些操作符并不关心他们的操作数是字符串,数字或参考。他们只返回第一个使整个表达式为真或假的值。这不影响返回值的布尔意义,但是却是返回的值更加有用。
 这个特性将帮助我们给变量,函数,或者一个长表达式 提供一个默认值。这有一个||操作符的例子,例子中如果$bar为真则给$foo赋值为$bar,如果$bar为假,就赋值为"DEFAULT VALUE":

 

$foo = $bar || "DEFAULT VALUE";

这还有一个例子:

#把 $dir设成程序的第一个参数,如果这个参数没有给出,则赋值为默认值“/tmp”


dir = shift(@ARGV) || "/tmp";

#你也可以完全不改变@ARGV


$dir = $ARGV[0] || "/tmp";

如果程序的第一个参数恰好是0怎么办呢,我们就不能再使用||了,一位0是会被看做假的,尽管它就是我们需要的值也不行。我们必须采用perl中唯一的三元操作符“? :”

 

$dir = defined($ARGV[0]) ? shift(@ARGV) : "/tmp";
#我们还可以写成下面这样,虽然语义略有不同

$dir = @ARGV ? $ARGV[0] : "/tmp";
#因为在这个三元操作符的第一个操作数是一个标量环境,所以它实际检查的是参数列表的数量,
#如果没有参数结果当然只能是假,也就自然使用了默认值“/tmp”

下面这行代码将使散列%count中的值自增,它的键一般是$shell,只有$shell等于假的时候为默认值“/bin/sh”:

 

$count{ $shell || "/bin/sh" }++;

你还可以把数个二选一的操作连接起来,就想下面的例子一样,第一个给出真的表达式将被返回:

 

#在unix系统上,找当前用户的用户名

$user = $ENV{USER}
     || $ENV{LOGNAME}
     || getlogin( )
     || (getpwuid($<))[0]
     || "Unknown uid number $<";

&&操作符也完成类似的工作。但是它返回第一个等于假的操作数(表达式),因为我们更对等于真的表达式感兴趣,所以我们很少使用它。关于它的一个演示将在菜单13.12和14.19中。

“||=”这个操作符看上去有点古怪,但是他却和perl的其他二元赋值操作符一样的工作。perl中这样的操作符原理都一样:$VAR OP= VALUE 意味着 $VAR = $VAR OP VALUE; 例如:$a += $b 和 $a = $a + $b 是一个意思。所以 ||= 被用来把变量设置成它自己,除非它等于假。(||操作符只简单的检测变量是真是假,它不关心变量是否被定义)

这有一个 ||= 的例子,如果$starting_point还没被设定一个值就把它的值设成"Greenwich",这里我们假设$starting_point不应该是0或“0”。如果它真的是这样的值,那么改变它也是正确的。

 

$starting_point ||= "Greenwich";

在分配值的时候,你不可以使用or操作符取代||操作符。因为or操作符的优先级太低了。比如,$a = $b or $c 和 ($a = $b) or $c 是等效的。显然这不是你想要的。

不要以为|| 和||= 的功能可以扩展到操作数据和散列。它们不能那样工作,因为在他们左面的操作数将带来一个标量环境。所以我们必须像下面演示的那样去达到相同的目的:

 

@a = @b unless @a; # 如果@a不为空就赋值

@a = @b ? @b : @c;

将来perl将支持新的操作符:// //= 和err。你读这篇文章的时候它可能已经支持了。这些操作符将像逻辑操作符||一样工作,只不过它将测试变量是否被定义而不是测试真假。例如下面的每一对语句都是等效的:

 

$a = defined($b) ? $b : $c;
#等于

$a = $b // $c;

$x = defined($x) ? $x : $y;
#等于

$x //= $y;

defined(read(FH, $buf, $count) or die "read failed: $!";
#等于

read(FH, $buf, $count) err die "read failed: $!";

这三个操作符已经出现在了perl的5.9版本中,这是一个测试版本,他们也将出现在5.10这个稳定版中,也将肯定用于perl6.

1.2.4 参考

操作符||的详细说明在perlop(1) 和大骆驼书的第三章;函数defined和exists在perlfunc(1)和大骆驼书29章。

 

阅读(313) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~