【问题标题】:What values should a boolean function in Perl return?Perl 中的布尔函数应该返回什么值?
【发布时间】:2026-02-21 04:35:01
【问题描述】:

小问题

在 Perl 代码库中一致表示真假的最佳方法是什么?

  • 1 / 0?

  • 1 / Perl 原生布尔运算符的特殊空字符串
    返回?

  • undef?

  • ()(即空列表)?

问题背景

我们都知道 Perl 在布尔值方面非常灵活,就像大多数事情一样。

例如,Perl 将以下内容视为 false:undef()、数字 0(即使写为 000 或 0.0)、空字符串、'0'(包含单个 0 数字的字符串)。 Perl 将以下内容视为真:任何其他标量值,1-1,其中包含空格的字符串 (' '),'00' 字符串中的多个 0,"0\n"('0'后跟换行符)、'true''false''undef' 等。另外,数组到标量和列表到标量的转换意味着您通常可以避免使用空数组作为错误值. (感谢http://perlmaven.com/boolean-values-in-perl 获得被 Perl 接受为真或假的标量值的部分列表。)

但是考虑到所有这些被视为真或假的值,Perl 布尔函数应该返回什么?

  • 1/0
  • -1/0(不)
  • 1/undef
  • 1/""

如果您使用这些约定中的任何一种,您很快就会发现您编写的代码的行为不如普通 Perl 代码好。您将无法将 $a<$b 替换为 custom_less_than($a,$b) 并使其工作方式完全相同。

考虑:

> perl -e 'use warnings; 
           sub my_eq { return ( $_[0]==$_[1] ? 1 : 0 ) }
           print "compare (1==0) <<".(1==0).">>"
                 ." to my_eq(1,0) <<".my_eq(1,0).">>"
                 ."\n" ;'
Output:
compare (1==0) <<>> to my_eq(1,0) <<0>>

当您自己编写时,从 Perl 中的布尔函数返回值的最著名方法是什么?

也许您希望您的代码与 Perl 类似,可以替代 Perl 现有的布尔运算符。或者您可能想要像 1/0 这样的数值。或者您可能来自 LISP,并期望 Perl 的 undef 被用于 LISP 的 nil 来表示 false(但随后您会发现 Perl 将许多其他值视为 false 的隐式处理)。

【问题讨论】:

  • 旁注:字符串'0 but true' 是一个很好的了解。它被 Perl 识别为“特殊”0,因此即使您启用了 strictwarnings(这将反对在数字上下文中使用具有非数字内容的字符串),它会默默地被视为数字0,但作为布尔值 true。
  • @Сухой27:考虑 > perl -e '使用警告; sub my_eq { return ( $_[0]==$_[1] ? 1 : 0 ) } 打印 "比较 (1==0) > 到 my_eq(1 ,0) >\n" ;'比较 (1==0) > 到 my_eq(1,0) >
  • 顺便说一句,我发布了这个 Q 并自己回答了这个问题,因为我希望当我开始使用 Perl 时有人告诉我使用 !!0 和 !!1 1994. 相反,我把我的 C 1/0 和我的 LISP t/nil(映射到 1/undef)带到了 Perl 中,这让我一次又一次地头疼。
  • true返回1,false返回0,不用担心。
  • @AndyLester:即使return 0 在列表上下文中为真?

标签: perl boolean undef


【解决方案1】:

我为布尔真值返回 1。我真的看不出!!1 除了混淆之外还有什么。

但我通常不返回布尔值的 false 值。这是因为裸return 将根据子例程的调用方式返回适当的值。 return 的文档是这样说的:

如果没有给出 EXPR,则在列表上下文中返回一个空列表,在标量上下文中返回未定义的值,并且(当然)在 void 上下文中什么都没有。

这很重要,因为真值和假值在标量和列表上下文之间可能存在细微差别。想象一个像这样的子程序:

sub some_boolean {
  if ($some_condition) {
    return 1;
  else {
    return undef; # same effect with any scalar value
  }
}

如果在标量上下文中调用,这会很好。

if (some_boolean()) {
  ...
} else {
  ...
}

一切都按预期工作。但是如果你在列表上下文中调用它,事情就会变得有点奇怪。

my @array = some_boolean();
if (@array) {
  ...
} else {
  ...
}

在这种情况下,永远不会调用 else 块。在列表上下文中,您的子例程返回一个包含单个标量(值 undef)的列表,因此 @array 有一个元素,if (@array) 测试始终为真。

当然,您的子例程并不打算在列表上下文中调用。但是你无法控制其他程序员如何使用你的代码。

但是如果子程序是这样写的:

sub some_boolean {
  if ($some_condition) {
    return 1;
  } else {
    return;
  }
}

一切都会按预期进行。如果您的子例程在标量上下文中调用,它将返回一个标量 false 值,如果在列表上下文中调用,它将返回一个空列表。

在我看来,从子例程返回显式错误标量值总是值得怀疑的。

如果您想返回一个明确的标量 false 值,那么最好检查调用上下文并在错误时采取适当的措施。

croak 'Subroutine called in list context.' if wantarray;

更新:回答此评论。

IIRC 我尝试使用这种方法,但放弃了它,因为它会产生更多关于未定义值的警告 - 即它不是现有 Perl 1/!!0 比较的直接替代品,也不是 1/0。考虑perl -wle 'print "a()=&lt;&lt;".a()."&gt;&gt;\n"; sub a {if(@_) {return 1} else {return}} ',与return !!@_

布尔值的作用是你可以询问它是真还是假。就这些。在我看来,你不应该期望只打印一个布尔值。您通常可以在不触发警告的情况下打印布尔值这一事实很好,但不应依赖。如果我想打印一个布尔值,我总是会使用某种逻辑检查(可能是三元运算符)来做到这一点。所以我会这样写你的例子:

$ perl -wle 'print "a()=<<".(a() ? "True" : "False").">>\n"; sub a {if(@_) {return 1} else {return}}'

我只是重申我的原点。如果您为 false 返回任何标量值,并且有任何方式可以在列表上下文中调用您的子例程(甚至是意外),那么您已经在代码中引入了潜在的错误。

仅此一点,就值得在打印布尔值之前对其进行解码。

【讨论】:

  • 好点。如果不返回任何内容或使用 wantarray 是最好的做法,那么......我将尝试将其塞入我刚刚扩展以处理更便携和可打印的 1/0 表单的答案中。或者可能只是替换答案。或者只是选择您的最佳答案。我会担心用户说“嘿,这个函数应该返回一个值!”,所以我可能总是评论这样的空返回。总的来说,寻找这样的东西是我首先发布这个问题的原因。
  • 您是否有首选方法将某些可能不遵守您的“return 1/return”(return-nothing for false)约定的函数转换为您的约定?除了表格说“if(foreign_function()){return 1;} else {return;}”
  • IIRC 我尝试使用这种方法,但放弃了它,因为它会产生更多关于未定义值的警告 - 即它不是现有 Perl 1/!!0 比较的直接替代品,也不是为 1/0。考虑 perl -wle 'print "a()=>\n"; sub a {if(@_) {return 1} else {return}} ',而不是 return !!@_
  • 它似乎也不允许 ?: 表达式。有时你可以说 (cond()?1:()),但我不太确定我有时会收到警告。
  • 但是,总的来说,如果 1/() 是布尔值的一致方案,那肯定会很好。
【解决方案2】:

---+简短回答

以下是 Perl 中布尔值的两个自洽方案:

  • 1/0 - 可打印和便携
  • 1/!!0 - 最像 Perl 的原生布尔函数

1/0可能是其他语言的程序员最熟悉的,比如 C 或 Python。您可以打印1/0 布尔值、添加它们等等。但是... Perl 的原生布尔运算符不是 1/0 值,return $a&lt;0return 1 if $a&lt;0; return 0 不同。

1/0!! 是我尝试为 Perl 的本机布尔运算符使用的方案创建一个缩写名称:1 表示真,一个空字符串,经过特殊标记,以便在用于算术或插入字符串时不会产生警告. !!0 是产生这个特殊的 Perl 假值的最简单的方法之一,并且应该为使用 C 等许多语言的程序员所熟悉,作为标准化布尔值的一种方式。您可以添加1/0!!,也可以打印1/0 布尔值,只要您不在乎假值是否不可见,即空字符串。

避免意外在同一个函数或库中混合数字 1/0、Perl 的本机条件、undef 和其他方案。

故意混用时,使用转换运算符如

  • !!$bool_0or1 转换为传统的 1/!!0Perl 值
  • (0+($a&lt;0)) 将 Perl 关系结果转换为 1/0
  • (!!any_other_boolean())
  • (0+any_other_boolean())
  • ($other_bool?1:()) 从其他布尔方案转换为 1/()
  • ($other_bool?1:undef) 从其他布尔方案转换为 1/undef

问:除了?:,还有其他更短或类似前缀的符号吗?

还有一些可能的方案

  • 1/() - 更准确地说,返回 1 或不返回 - 可以捕获
    一些 Perl-ish 错误,例如返回布尔标量 false,如 0 或 undef 在列表上下文中,它将变为 true
  • (1)/(0) - 返回一个包含 1 的长度为 1 的列表,或者一个空的 列表。类似于1/(),在真实和 false 是数组。
  • 1/undef - 另一种可能性,捕获 1/() return 1 的错误 或者没有可能导致

我不愿推荐这些。至少,1/() 是不一致的,但是……它们肯定已经被 Perl 程序员使用,所以你应该准备好处理使用这些方案的代码。 IE。准备调试由这些方案引起的错误。

1/() 是我尝试为返回 true 的函数 return 1; 和返回 false 的函数执行 return; 的方案创建缩写名称,即没有操作数值的返回。 IE。 返回 1 或不返回任何内容。我相信 return nothing 等同于return ();。此方案可保护您免受程序员在列表上下文而不是标量上下文中评估您的函数引起的错误。但它会使您暴露于诸如{1=&gt;return_nothing_if_false(),2=&gt;return_nothing_if_false()} 之类的错误(因为您可能不想要{1=&gt;2}

顺便说一句,我认为执行(1)/() 的方案可能更一致。这将使您能够始终如一地拥有这种布尔类型的变量,当然是@array 变量。

请注意,1/undef 不等同于上述任何一个。 1/undef 布尔变量在 false=undef 被打印或插值或在算术中使用时发出警告,但当 true=1 被如此操作并在列表上下文中评估为 true 时不会发出警告。有人可能会说它具有所有方案中最差的特性。

对于1/()(1)/() 或 1/undef 的这些方案,我犹豫不决。至少,1/() 是不一致的

所有这三个方案1/()(1)/() 或 1/undef 都会将您暴露在诸如 {1=&gt;f1_return_nothing_if_false(),2=&gt;f2_return_nothing_if_false()} 之类的错误中,因为如果两者都为假,您可能不希望 {a=&gt;"b"}{a=&gt;1,b=&gt;1} 如果两者都为假是真的。至少如果 f1 返回 true 而 f2 返回 false,或者反之亦然,您将收到关于奇数大小哈希的警告。

调用函数的程序员可以控制是否在列表或标量上下文中计算它,但她可能无法控制它是否返回真或假。

恕我直言,如果您使用 1/()(1)/() 或 1/undef,则无法在数组上下文中安全地调用此类函数,例如构建关键字参数 foo(kw=&gt;boolfunc(),...)foo({kw=&gt;boolfunc(),kw2=&gt;...},...)。不必分散!或全部为 0+。

---+中等长度答案

概括原始答案:

Perl 有多种表示真理的方式。或者更确切地说,Perl 将许多不同的值解释为真或假。

如果您要创建一系列相关函数,即。一个库,建议您选择以下知名方案之一,并在您的库中始终如一地使用它:

  1. Truth 1/0 - 数字 - 与其他语言最便携,更易于打印

  2. Truth 1/!!0 - 最像标准 Perl 关系运算符,可移植性较差,可打印性较差(除非您希望 false 不可见)

这个答案强调布尔函数或方法,谓词。它不是试图讨论非布尔函数,它们返回实际的东西,如数字、字符串或引用 - 除了下面简要介绍。

@DaveCross 提出了另一个有趣的方案

  1. return 1 / return 什么都没有(几乎是1/(),空列表)

我记得 Perl 早期的一个方案 - 在 refs 之前,我认为甚至在 undef 是可以返回的值之前。但是 IIRC 这个方案和 use warnings 存在问题,可能还有?:,所以我犹豫是否完全推荐它,直到有人更好地解释如何避免此类问题。可能使用wantarray

---++选择1/0或1/0!! (原生 Perl)并保持一致

我建议您选择其中一种布尔方案,并始终如一地使用该方案。

1/0 布尔方案可能最适合其他语言。

1/!!0 方案将使您的代码更接近原生 Perl 运算符。

如果你使用1/!!0方案,不要说“return 0”,说return !!0

如果你使用1/0方案,不要说return $a &lt; $b,而是说return 0+($a &lt; $b)

如果您调用的代码使用不同的布尔方案(或者可能没有一致的方案),请使用诸如

之类的运算符转换为您在代码中使用的布尔方案
  • !! 规范化标准 Perl 1/0!! 布尔值
  • 0+1* 从标准 Perl 1/0 转换为更便携的 1/0 布尔值!!布尔值
  • ?: 和 Perl 的所有其他工具库中的 undef 和字符串可能会或可能不想被视为错误或失败

如果查看返回 ref 或 undef 的函数的返回值

  • 如果 1/!!0 类似 Perl 的布尔值,请说返回 !!ref_retval_func()defined ref_retval_func()

  • 如果1/0 更便于携带布尔值,请说返回0+!!ref_retval_func()0+(defined ref_retval_func())

下面的细节太多了。

---++ 可能?:返回 1 或什么都不返回方案(可能是 1/()?)

@DaveCross 提出了一个有趣的建议:

  • 为布尔真值返回 1。

  • 对于 Boolean false 值不返回任何内容。那是因为一个裸露的
    return 将返回一个适当的值,具体取决于
    子程序已被调用。退货文件是这样说的:

    如果没有给出 EXPR,则在列表上下文中返回一个空列表,在标量上下文中返回未定义的值,并且(当然)在 void 上下文中什么都没有。

---++ 反推荐:不要混合布尔方案 例如,在同一个函数或库中,不要这样做

return $arg1 < $arg2;  # returning a standard Perl 1/!!0 Boolean

在一个地方,然后在其他地方,或者在相同代码的后续演变中,这样做

return 0; 
return undef; 
return ''; 
return (); 

即选择一种布尔方案,并保持一致。主要是,这涉及到错误值的一致性;在较小程度上是真正的价值。

---+过分凌乱的细节

---++ 在别处讨论 Perl 的许多真理价值

What do Perl functions that return Boolean actually returnWhy does Perl use the empty string to represent the boolean false value? 等帖子讨论了 Perl 布尔函数和运算符实际返回的内容。基本上是特殊值,其行为由 Perl 手册指定。

@cim 链接到 perl 手册:http://perldoc.perl.org/perlsyn.html#Truth-and-Falsehood

真假

数字 0、字符串 '0' 和 "" 、空列表 () 和 undef 在布尔上下文中都是错误的。所有其他值都为真。 对真实值的否定!或不返回一个特殊的假值。 当评估为字符串时,它被视为 "" ,但作为数字,它 被视为 0。大多数返回 true 或 false 的 Perl 运算符的行为 这边。

类似http://perldoc.perl.org/perlop.html#Relational-Operators

关系运算符

返回 true 或 false 的 Perl 运算符通常返回的值 可以安全地用作数字。例如,关系运算符 在本节中,下一节中的相等运算符返回 1 对于定义的空字符串 "" 的 true 和特殊版本,它 算作零,但不受有关不正确数字的警告的影响 转换,就像“0 但真实”一样。

不幸的是,What do Perl functions that return Boolean actually return 的接受答案 讨论内部结构,然后推荐

my $formatted = $result ? '1' : '0';

这又回到了我们开始的地方。

@amon 在对问题 What do Perl functions that return Boolean actually return 的评论中向我们展示了光芒 (!!)

旁注:您可以将任何值转换为相应的布尔值 双重否定。这导致了!!伪运算符。非常有用 返回通用的真值或假值而不是一些魔法 数字。 – 阿蒙 2012 年 11 月 22 日 22:11

这些特殊的布尔值似乎没有任何文字。然而,产生它们的方法有很多:(0&lt;0)(0&lt;1) 等。(!!1)(!!0) 可能是最好的——尤其是因为在某些 C/C++ 编程圈子中它们用于类似目的。另外,!! 可以应用于传入的真值,以将其“标准化”为这个“Perl 标准”布尔值。

---++ 反推荐:不要混合布尔方案 例如,在同一个函数或库中,不要这样做

return $arg1 < $arg2;  # returning a standard Perl 1/!!0 Boolean

在一个地方,然后在其他地方,或者在相同代码的后续演变中,这样做

return 0; 
return undef; 
return ''; 
return (); 

即选择一种布尔方案,并保持一致。主要是,这涉及到错误值的一致性;在较小程度上是真正的价值。

例如避免从

演化代码
return $arg1 < $arg2;  # returning a standard Perl 1/!!0 Boolean

if( $arg1 < $arg2 ) {
     log_or_print('found $arg1 <$arg2');
     # other stuff to do if less-than
     return 1;
} else {
     log_or_print('found not( $arg1 < $arg2)');
     # other stuff to do if not-less-than
     # which may not be the same thing as greater-than-or-equal
     return 0;
}

if( $arg1 < $arg2 ) {
     ...
} else {
     ...
     return undef;
}

从其他地方来到 Perl,您可能会认为它们是等价的,而且大多数情况下是等价的,但如果您在测试中执行诸如打印布尔返回值之类的操作,您会发现差异。

如果您从 Perl-ish 布尔运算符演变代码

return $arg1 < $arg2;  # returning a standard Perl 1/!!0 Boolean

进化成

if( $arg1 < $arg2 ) {
     log_or_print('found $arg1 <$arg2');
     # other stuff to do if less-than
     return 1;
} else {
     log_or_print('found not( $arg1 < $arg2)');
     # other stuff to do if not-less-than
     # which may not be the same thing as greater-than-or-equal
     return !!0;
}

如果您希望行为尽可能接近相同。注意 false 返回的 !!0,据我所知,没有更简单的方法可以构造 Perl 对 false 的特殊返回值。

相反,如果你想使用 1/0 布尔方案,它们的原始代码应该写成

return 0+($arg1 < $arg2);  # returning a standard Perl 1/!!0 Boolean

---++ 从 value / undef 创建谓词

同样,你可能会想使用诸如

之类的功能
sub find_string_in_table {
   # returns string value if found, undef if not found
   return $lookup_table->{$_[0]}; 
}

并将其重构为谓词

sub is_string_in_table {
   return find_string_in_table(@_);
}

然后可能会演变为进行健全性检查或性能优化。

sub is_string_in_table {
   return 0 
       # don't even bother for long strings
       if 1000000 < length($_[0]);
   return find_string_in_table(@_);
}

这既不是 1/0 也不是 1/!!0,也不是始终如一的 value/undef。

(注意:我不是说这个预检查是性能优化 --- 但我是说性能优化可能看起来像上面。性能优化是我的专长之一,你希望这样的优化是重构. 当优化的代码表现更好时,它很糟糕,但在某些地方使用它时会中断。因此,我对执行完全一样的代码感兴趣......无论它被替换,就像本机 Perl 关系运算符一样。完全意味着完全。)

如果您使用的是标准 Perl-ish 布尔值,请改为执行以下操作。

sub is_string_in_table {
   return !!0 
       # don't even bother for long strings
       if 1000000 < length($_[0]);
   return (defined find_string_in_table(@_));
}

或者如果您使用的是 1/0 布尔值

sub is_string_in_table {
   return 0 
       # don't even bother for long strings
       if 1000000 < length($_[0]);
   return 0+(defined find_string_in_table(@_));
}

如果使用 find_object_ref_in_table 而不是 find_string_in_table,您可能只需要返回 0+!!find_string_in_table(@_),因为您不需要担心像 q()"0" 这样的字符串。

如果您希望您编写的代码中的布尔函数表现得像本机 Perl 运算符,则返回 (!!1) 表示真,返回 (!!0) 表示假。

即0/1,但使用 ! 逻辑否定两次运算符将您的 1 或 0 转换为 Perl 的“本机”布尔值。

例如

sub my_boolean_function {
      ... 
      return !!1; # true 
      ...
      return !!0; # false
}

**---+ 0/1 --> 1/!!0 转换**

如果你考虑!作为从“元布尔”到“特殊布尔”的转换,

将 1* 或 0+ 视为从特殊布尔值到普通 0/1 布尔值的转换。

例如print "test".(1*($a eq $b))."\n"

例如print "test".(0+($a eq $b))."\n"

?:更笼统,但更冗长。

---++ 非布尔错误返回

这个问题和答案强调布尔函数或方法,谓词。它不是试图讨论非布尔函数,它们返回实际的东西,如数字、字符串或引用 - 除了下面简要介绍。

将返回值扩展为表示特殊情况(例如失败、无效输入等)是“不错的”,并且可以在 IF 语句或其他控制流(例如 and 和 or 运算符)的上下文中对其进行评估,通常用于处理此类错误,例如提供默认值。

我们将对非布尔函数的讨论限制在这个简短列表中:

  • ref / undef :用于返回典型 http://perldoc.perl.org/perlobj.html 对象、对祝福哈希或其他类型的引用的函数。返回 undef 错误、未找到等。

  • 任何值/undef:对于返回任何类型值、标量数字或字符串、标量引用(无论是祝福还是未祝福)的函数。

value/undef 在undef 不是合法返回值时效果最佳,并且当 undef 是合法值时可能会出现问题。想象一个返回哈希字段值的访问器函数,$hash->{field}——该字段可能合法地具有值{ field =&gt; undef },因此返回 undef dfoes 无法区分不存在的字段和存在但具有的字段一个 undef 值。

  • 任意字符串,可以根据上下文解释为数字或布尔值。
  • "0 but true" - 我真的不想进入这个,但是看看What does "0 but true" mean in Perl? 对字符串 "0 but true" 的特殊处理。其他字符串在转换为数字时会发出警告,但“0 但为真”不会。
  • “0E0” - 类似地,一些 Perl 代码返回字符串“0E0”,其计算结果为 0 作为数字,但作为布尔值返回 true

GLEW 个人意见:因为我编写的代码经常需要移植到其他语言,所以我不喜欢利用像 0+"0 but true" 这样的 Perl 特定技巧。 "0E0" 至少更便携,如果你想象在 C 之类的其他语言中,函数 convert_string_to_float("0E0")convert_string_to_int("0x0")。我更喜欢"0x0",因为它与 x 看起来很特别,而0x0 是一个整数值,而0E0 在某些语言中被解释为浮点数,因此更容易出错。

---++ 可能?:返回 1 或什么都不返回方案(可能是 1/()?)

@DaveCross 提出了一个有趣的建议:

  • 为布尔真值返回 1。

  • 对于 Boolean false 值不返回任何内容。那是因为一个裸露的
    return 将返回一个适当的值,具体取决于
    子程序已被调用。退货文件是这样说的:

    如果没有给出 EXPR,则在列表上下文中返回一个空列表,在标量上下文中返回未定义的值,并且(当然)在 void 上下文中什么都没有。

这很重要,因为真值和假值在标量和列表上下文之间可能存在细微差别。想象一个像这样的子程序:...

@DaveCross 继续说明如果在数组上下文中评估布尔函数,返回空列表以外的任何值如何导致错误性丢失。甚至 @array=(undef) 的评估结果都是 true。

我希望这个方案能够奏效。我想我几年前在 Perl 4 或更早的版本中使用过它,但是当 use warnings 开始成为该做的事情时就放弃了。

就我的记忆而言,我也遇到了条件表达式的问题?:遵守这个约定。

我都尝试过“return;”和“return();”

考虑

%  perl -wle 'print "a()=<<".a().">>\n"; sub a {if(@_) {return 1} else {return}}'
Use of uninitialized value in concatenation (.) or string at -e line 1.
a()=<<>>

%  perl -wle 'print "a()=<<".a().">>\n"; sub a {if(@_) {return 1} else {return ()}}'
Use of uninitialized value in concatenation (.) or string at -e line 1.
a()=<<>>

%  perl -wle 'print "a()=<<".a().">>\n"; sub a { return @_ } '
a()=<<0>>

%  perl -wle 'print "a()=<<".a().">>\n"; sub a { return !!@_ } '
a()=<<>>

%

---+底线

使用1/0(可打印和便携)、1/0!!(最类似于 Perl 的本机布尔函数)。

可能return 1return 什么都没有,这与1/() 几乎相同。 (但我在使用这种方法时遇到了问题。)

避免在同一函数或库中混合数字 1/0、Perl 的原生条件、undef 和其他方案。

最后,如果你曾经做过

$>  perl -wle 'print false && true'

你可能已经收到了

Unquoted string "false" may * with future reserved word at -e line 1.
Unquoted string "true" may * with future reserved word at -e line 1.
Bareword found in conditional at -e line 1.
true

所以似乎有一天 Perl 可能会为布尔值提供一个“官方”方案,其值为 true 和 false。

我想知道它们会如何表现?

【讨论】:

  • 嗨。我没有使用 Perl 编程,但我对您提出的“本机”!!0 进行了非常简单的酸性测试:即,我评估了print !!0, "\n";。 Perl 没有打印任何东西。只是看起来是一个空白行。不具有由一些可见字符组成的正面、非空白印刷表示的虚假对象是不推荐的选择。我也尝试以同样的方式打印!!1;呈现为1。 (1 是原生的吗?或者它是不是 1 之外的其他对象,打印时看起来像它?)也许你应该坚持使用 10,不要太聪明。跨度>
  • @Kaz Perl 的比较运算符返回一个字符串化为空字符串的值:print 1 == 2。因此,语言中已经有一个先例。
  • @Kaz:巧合的是,我添加了一个建议,使用 (1*$perlish_boolean) 将 Perl 的 1/特殊空字符串转换为非 Perl 程序员更熟悉的 1/0。
  • @Kaz:顺便说一句,我同意你的观点:每个值都应该有一个可见的默认打印格式。但是空字符串呢?恕我直言,每种语言都应该具有可以使每个值可见的打印功能。只是,在 Perl 中,`print' 函数并不是表现良好的 make-every-value-visible 函数。
  • 我强烈建议不要使用 !!在生产代码中,因为它降低了可理解性。我从喜欢洒的程序员那里看到了太多的wtf代码!无处不在....