Perl布尔,否定(以及如何解释)?

时间:2013-07-05 14:16:37

标签: perl

我是新来的。在阅读了如何询问和格式化之后,我希望这将是一个好问题。我对perl不是很熟练,但它是我最熟悉的编程语言。

我尝试将Perl应用于现实生活,但我没有得到很好的理解 - 特别是不是来自我的妻子。我告诉她:

  

如果她晚上没有给我带来 3 啤酒,那意味着我得到了零(或没有)啤酒。

正如你可能猜到的那样,没有太大的成功。 :(

现在事实上。来自perlop

  

一元“!”执行逻辑否定,即“不”。

语言,有boolean种类型(只能有两个“值”)是可以的:

  

如果它不是一个值 - > 必须另一个。

如此自然:

!true  -> false
!false -> true

但是perl没有boolean个变量 - 只有truth system,一切都不是0'0' undef,{{1} } 是真的。将逻辑否定应用于非逻辑值时出现问题,例如号。

E.g。如果某个数字不是3 ,则表示 IS ZERO 或为空,而不是现实生活含义,如果某些内容不是3,意味着它可以是除了3 之外的所有东西(例如也是零)。

所以下一个代码:

''

打印:

use 5.014;
use Strictures;

my $not_3beers = !3;

say defined($not_3beers) ? "defined, value>$not_3beers<" : "undefined";
say $not_3beers ? "TRUE" : "FALSE";

my $not_4beers = !4;
printf qq{What is not 3 nor 4 mean: They're same value: %d!\n}, $not_3beers if( $not_3beers == $not_4beers );
say qq(What is not 3 nor 4 mean: @{[ $not_3beers ? "some bears" : "no bears" ]}!) if( $not_3beers eq $not_4beers );

say ' $not_3beers>',  $not_3beers, "<";
say '-$not_3beers>', -$not_3beers, "<";
say '+$not_3beers>', -$not_3beers, "<";

此外:

defined, value><
FALSE
What is not 3 nor 4 mean: They're same value: 0!
What is not 3 nor 4 mean: no bears!
 $not_3beers><
-$not_3beers>0<
+$not_3beers>0<

什么是不是4 IS 1 ,而不是4!

上述与妻子的陈述是“假的”(意思是0):),但是真的想教我的儿子 Perl和他,过了一会儿,问我的妻子:为什么,如果什么不是3意味着它是0?

所以问题是:

  • 如何向我的儿子解释这个
  • 为什么perl有这个设计,为什么perl -E 'say !!4' 每次都是1
  • 这里有什么“后面”需要的东西比!0不是任何随机数,而是0。
  • 正如我已经说过的,我不太了解其他语言 - 每种语言都是!0

4 个答案:

答案 0 :(得分:11)

我认为你在很大程度上关注否定,而太多关于Perl布尔的意思。

历史/实施视角

什么是真相?检测到更高电压x伏特。

在更高的抽象级别:如果此位置位。

比特序列的抽象可以被认为是整数。这个整数是假的吗?是的,如果没有设置位,即整数为零。

面向硬件的语言可能会使用这种真理定义,例如: C和所有C后代都包含Perl。

0的否定可能是按位否定 - 所有位都翻转为1 - ,或者我们只将最后一位设置为1。结果通常分别解码为整数-11,但后者更节能。

务实观点

方便在处理计数时将所有数字都想象为 true 为零

my $wordcount = ...;

if ($wordcount) {
  say "We found $wordcount words";
} else {
  say "There were no words";
}

say "The array is empty" unless @array;  # notice scalar context

像Perl这样的实用语言可能会认为零是假的。

数学视角

没有理由说任何数字都是假的,每个数字都是明确定义的实体。真理或虚假仅通过谓词表达,表达可以是真或假。只有这个真值才能被否定。 E.g。

¬(x ≤ y) where x = 2, y = 3

是假的。许多具有强大数学基础的语言不会考虑任何错误,而是一种特殊的虚假价值。在Lisps中,'()nil通常为false,但0通常为真。也就是说,如果值不是零,则该值仅为真!

在这种数学语言中,!3 == 0可能是类型错误。

回复:啤酒

啤酒很好吃。任何数量的啤酒都是好的,只要你有一个:

my $beers = ...;

if (not $beers) {
  say "Another one!";
} else {
  say "Aaah, this is good.";
}

啤酒计数变量的升级只是告诉我们你是否有啤酒。考虑!!是一个boolification运算符:

my $enough_beer = !! $beers;

boolification并不涉及具体数量。但也许任何数量≥3都是好的。然后:

my $enough_beer = ($beers >= 3);

否定啤酒是不够的:

my $not_enough_beer = not($beers >= 3);

my $not_enough_beer = not $beers;

fetch_beer() if $not_enough_beer;

Perl标量并不代表整个世界。特别是,not 3不是所有不是三个实体的集合。表达式3是真值吗?是。因此,not 3是一个假名值。

4 == not 3的建议行为可能是不合适的:4和“所有不是三的东西”不是相等,这四个只是其中之一许多事情不是三个。我们应该写得正确:

4 != 3    # four is not equal to three

not( 4 == 3 )   # the same

!not视为逻辑否定 - 可能会有所帮助,但之外不会。

如何教

引入数学谓词可能是值得的:表达式可以是真或假。如果我们只通过明确的测试“创造”真实性,例如length($str) > 0,那么您的问题就不会出现。我们可以为结果命名:my $predicate = (1 < 2),但我们可以决定永远不打印出来,而是:print $predicate ? "True" : "False"。这避免了考虑 true false 的特殊表示的问题。

直接考虑值为真/假将只是一个捷径,例如foo if $x可以被视为

的捷径
foo if defined $x and length($x) > 0 and $x != 0;

Perl就是关于捷径的。

教授这些快捷方式,以及perl的各种上下文以及它们出现的位置(数字/字符串/布尔运算符)可能会有所帮助。

  • 列出上下文
    • 偶数大小的列表上下文
  • 标量上下文
    • 数字上下文
    • 字符串上下文
    • 布尔上下文
  • 虚空背景

答案 1 :(得分:8)

  
      
  • 正如我已经说过的,我不太了解其他语言 - 每种语言都是!3 == 0?
  •   
  • 是。在C(以及C ++)中,它是相同的。

    void main() {
        int i = 3;
        int n = !i;
        int nn = !n;
        printf("!3=%i ; !!3=%i\n", n, nn);
    }
    

    打印(参见http://codepad.org/vOkOWcbU

    !3=0 ; !!3=1
    

  
      
  • 如何向我的儿子解释这个
  •   
  • 很简单。 !3表示“与某些非假值相反,这当然是假的”。这被称为“上下文” - 在由否定运算符强加的布尔上下文中,“3”不是数字,它是真/假的陈述。

    结果也不是“零”,而只是方便Perl表示false的东西 - 如果在数字上下文中使用则变为零(但如果在字符串上下文中使用则为空字符串 - 请参阅{之间的差异} {1}}和0 + !3

      

    布尔上下文只是一种特殊的标量上下文,不会执行任何字符串或数字的转换。 (perldoc perldata


  
      
  • 为什么perl有这个设计,所以为什么!0每次都是
  •   

  
      
  • 这里有什么需要“落后”的东西比!0不是任何随机数,而是0。
  •   
  • 除了简单的实施之外没有别的。产生“1”比随机数更容易。

  • 如果你问一个不同的问题“为什么它是1而不是原来的#被否定得0”,答案很简单 - 到时候Perl解释器得到否定零,它不再知道/记住零是“!3”的结果,而不是导致值为零/假的其他表达式。

答案 2 :(得分:3)

如果您想测试一个数字不是3,请使用:

my_variable != 3;

使用语法!3,因为!是一个布尔运算符,首先将3转换为布尔值(即使perl可能没有官方布尔类型,它仍然以这种方式工作),因为它非零,意味着它被转换为等价的true。然后,!true产生false,当转换回整数上下文时,它会给出0。继续该逻辑显示!!3如何将3转换为true,然后将其转换为false,再次反转回true,如果此值为在整数上下文中使用,转换为1。对于大多数现代编程语言来说都是如此(尽管可能不是一些更以逻辑为中心的编程语言),尽管确切的语法可能会因语言而有所不同......

答案 3 :(得分:0)

逻辑上否定错误值需要选择某些值来表示结果的真值。 “1”和任何选择一样好。我会说返回哪个值并不重要(或者相反,重要的是你不要依赖任何特定的真值返回)。