为什么是 ”!!” Perl 中被认为是不好的形式吗?

2024-01-11

在最近的一次工作面试过程中,我提交了一些示例 Perl 代码,其中使用了所谓的“秘密”!! operator http://search.cpan.org/dist/perlsecret/lib/perlsecret.pod#Bang_bang。后来,在讨论代码时,一位面试官问我为什么选择使用它,并表示它被认为是不好的形式。他没有详细说明原因。

我和我的团队多年来一直使用这个运算符,但从未意识到它被认为是“糟糕的形式”。

“bang bang”运算符是否有副作用或其他意外行为?为什么它被某些人认为是“不好的形式”?有惯用的替代方法吗?

下面是我会考虑的几个例子!!可接受的和/或理想的。

  1. 编码练习中的实际代码,这是添加布尔值的示例:

    while (my $line = <$F>) {
        # snip
        exists $counts{lines} and $counts{lines} += !! chomp $line;
    }
    
  2. 使用布尔值作为哈希键(显然是一个简化的示例):

    sub foo {
        my ($input) = @_;
        my %responses = ( '' => "False", 1 => "True" );
        return $responses{ !! $input };
    }
    
  3. 在按位运算中使用布尔值,甚至pack():

    sub foo {
        my ( $a, $b, $c ) = @_;
        my $result = !!$a + (!! $b)<<1 + (!! $c)<<2;
        return $result;
    }
    
  4. 您需要进行类型转换以供外部库/进程使用,例如数据库,它只认为某些值是真实的:

    my $sth = $dbh->prepare("INSERT INTO table (flag,value) VALUES (?,?)")
    $sth->execute("i_haz_cheeseburger", !! $cheeseburger_string)
    

我称其为“坏形式”,因为它根本没有必要。您不需要在 Perl 中进行布尔转换。因此,往好了说,它是多余的,往坏了说,它是一种混淆。

虽然 Perl 中有一些非常好的技巧,但该语言的最大问题之一(至少在感知上)是它很容易“编写一次”代码。

毕竟,当您可以测试标量时,为什么需要对标量进行“双重否定”才能获得布尔值呢?

my $state = !! 'some_string';
if ( $state ) { print "It was true\n" };

Or:

if ( 'some_string' ) { print "It was true\n" };

这是真的——借助“秘密”运算符、基于标点符号的变量等,你可以编写一些极其难以理解的 Perl 代码。而且它会工作得很好——例如——我仍然认为这是一部杰作:3-D立体图,自复制源 http://www.perlmonks.org/?node_id=118799

但这不是“好代码”。对于“现实世界”的使用,您的代码需要清晰、易懂且易于排除故障。

关于替代方案;

while (my $line = <$F>) {
    # snip
    exists $counts{lines} and $counts{lines} += !! chomp $line;
}

这是...计算您成功的频率chomp我想是写了一行吗?所以基本上它只是计算输入中的行数。

为此,我会想“使用$.'。除非我错过了关于你的代码的一些深刻的东西?

“如果不咀嚼怎么办?”

好吧,好吧。怎么样:

 $counts{lines}++ if foo();

为了这:

sub foo {
    my ($input) = @_;
    my %responses = ( "" => "False", 1 => "True" );
    return $responses{ !! $input };
}

我会把它写成:

sub foo {
    my ($input) = @_;
    return $input ? "True" : "False";
}

对于最后一个条件 - 将标志打包到一个字节中:

sub flags {
    my @boolean_flags = @_;
    my $flags = 0;
    for ( @boolean_flags ) {
        $flags<<=1;
        $flags++ if $_;
    }
    return $flags;
}

print flags ( 1, 1, 1 );

或者也许如果你正在做类似的事情 - 借鉴如何Fcntl http://perldoc.perl.org/Fcntl.html通过定义要根据位置添加的值来实现这一点,因此您不必担心位置参数问题:

您可以通过使用标签来请求提供flock()常量(LOCK_SH、LOCK_EX、LOCK_NB和LOCK_UN):flock.

然后你可以:

flock ( $fh, LOCK_EX | LOCK_NB );

它们是按位定义的,因此它们通过or运算符 - 但这意味着它是幂等操作,其中设置LOCK_NB两次就不会了。

例如,

 LOCK_UN = 8
 LOCK_NB = 4
 LOCK_EX = 2
 LOCK_SH = 1

如果我们将问题扩展到不太主观的问题:

我正在询问避免的原因!

  • Perl 评估变量的“真实性”,因此实际上并不需要实际的逻辑布尔值。
  • 条件语句比其等效的布尔代数更清晰。if ( $somecondition ) { $result++ }$result += !! $somecondition.
  • 它在秘密操作员名单上because这很晦涩。您未来的维护程序员可能不会意识到这一点。
  • !!1 is 1, !!0 is dualvar('', 0)。虽然这非常灵活,但它可能会令人惊讶,特别是因为大多数人甚至不知道 Dualvar 是什么,更不用说!返回一。如果您使用三元,那么您将得到明确的值:$value ? 1 : 0
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么是 ”!!” Perl 中被认为是不好的形式吗? 的相关文章

  • 如何将 mongoTemplate 自动装配到自定义类型转换器中?

    我正在尝试创建一个转换器 它将通过对象 ID 从数据库中获取对象 但转换器中的 mongoTemplate 始终为空 org springframework core convert ConversionFailedException 失败
  • 检测 perl 中声明的包变量

    Given package main our f sub f sub g 1 我怎样才能确定 f 但不是 g 已宣布 即兴的 我以为 main g SCALAR 可能是未定义的 但它是一个善意标量参考值 背景 我想将一个变量导入到main
  • 检查值是否实现接口的说明

    我读过 Effective Go 和其他类似这样的问答 golang接口合规性编译类型检查 https stackoverflow com questions 17994519 golang interface compliance com
  • 如何在 BEGIN 块之外正确声明哈希?

    考虑这个简单的程序 您能解释一下为什么在取消注释前两行后输出会有所不同吗 我的哈希发生了什么use strict 如何修复程序以供使用use strict echo e key1 nkey2 nkey3 perl lne use stric
  • 如何将文本转换为标题大小写?

    我有一个文本文件 其中包含需要更改为标题大小写的标题列表 单词应以大写字母开头 但大多数冠词 连词和介词除外 例如 这个书名列表 barbarians at the gate hot flat and crowded A DAY LATE
  • Perl 的 grep 函数如何与正则表达式一起使用?

    以下 grep 函数如何工作 什么作用 0o1Iil do chars grep 0o1Iil 0 9 A Z a z use Data Dumper print Dumper chars 在 chars中生成以下内容 VAR1 0 VAR
  • Perl 导入到我的所有包中?

    我倾向于经常使用 Data Dumper 最终我的 pl 代码中每个包的顶部都有以下样板 use strict use warnings use Data Dumper Data Dumper Deparse 1 Data Dumper P
  • 如何在 perl 程序中查找打开的全局文件句柄

    我刚刚发现一个问题 我必须关闭所有打开的文件句柄才能让我的 Apache cgi 脚本继续 我将问题追溯到 Parse RecDescent usr bin env perl use strict use warnings use feat
  • 将 System.Drawing.Image 转换为 System.Windows.Media.ImageSource 但没有结果

    我想在我的 WPF 应用程序中将 Image 转换为 ImageSource 我使用正常工作的 Code128 库 已在 WinForms 应用程序中检查 下面的函数返回具有适当大小的 ImageSource 但没有任何内容可见 priva
  • 无法安装 WWW::Curl::Easy: SZBALINT/WWW-Curl-4.17.tar.gz : make NO

    我正在尝试在我的 Fedora 26 机器上安装 WWW Curl Easy gcc c I usr include D REENTRANT D GNU SOURCE O2 g pipe Wall Werror format securit
  • 不明白为什么当变量为整数时条件评估为 True

    我正在使用表现出以下行为的代码 假设我有一个变量d我把它赋给一个整数9 d 9 为什么以下语句有效 In 95 if d print d else print Did not print d 9 In 96 当 d 本身不是布尔值且未通过以
  • 如何将 Java 地图转换为在 Scala 中使用?

    我正在开发一个 Scala 程序 该程序调用 Java 库中的函数 处理结果并生成 CSV 有问题的 Java 函数如下所示 Map
  • 在 qx 运算符中将 perl 数组拆分为单独的参数

    我试图将一组参数传递给qx操作员 考虑 my files qw A txt B txt print qx ls files 这给出了错误 ls cannot access A txt B txt No such file or direct
  • 有没有办法匹配任意 Unicode 字母字符?

    我有一些文档经过 OCR 从 PDF 转换为 HTML 因此 他们最终会出现很多随机的 unicode 标点符号 而转换器会搞砸 即省略号等 他们还正确地有一堆非英语但仍然是字母字符 如 和俄语字符等 有没有办法制作一个匹配任何 unico
  • Perl:HTTP::微小删除留下损坏的锚标记

    我编写了一个脚本 该脚本收集从数据库读取的缓冲区内的所有 URL 检查该页面是否仍然存在 并使用 HTTP Tiny 从缓冲区中删除 URL 如果该 URL 无法访问或返回无效 问题是 HTTP Tiny 删除左锚标记 例如此处无效的文本
  • 检查一个数字是 int 还是 float

    在perl中 我想检查给定变量是否包含浮点数 为了检查我正在使用的 my Var 0 02 Floating point number if int Var Var floating point number 但上面的代码对于 0 0 不起
  • 如何在 Perl 中复制整个目录?

    我需要将整个目录复制到某个位置 最好的方法是什么 File Copy正如我所见 仅逐个文件复制 顺便说一句 我在Windows下工作 感谢帮助 也许调查一下文件 复制 递归 http metacpan org pod File Copy R
  • Perl 语言的目标是在运行时生成快速的程序吗?

    最近有朋友告诉我 看 Perl 从来就不是为了快而设计的 真的吗 我能找到的相关信息是来自维基百科 http en wikipedia org wiki Perl Overview 该语言旨在实用 易于使用 高效 完整 而不是美观 微小 优
  • 从 php 执行 bash 脚本并立即输出回网页

    我有一组 bash 和 Perl 脚本 开发在 Linux Box 上部署所需的目录结构 可选 从svn导出代码 从这个源构建一个包 这在终端上运行良好 现在 我的客户请求此流程的 Web 界面 例如 某些页面上的 创建新包 按钮将一一调用
  • Text::平衡和多行 xml

    看来我有点失落了 我需要解析一个大的 大约 100 mb 且相当难看的 xml 文件 如果我使用parsefile 它返回错误 文档元素后的垃圾 但它会很乐意解析文件的较小元素 所以我决定将文件分解为元素并解析它们 由于不鼓励使用正则表达式

随机推荐