【问题标题】:What is Perl's secret of getting small code do so much?Perl 让小代码做这么多的秘诀是什么?
【发布时间】:2010-04-11 12:31:38
【问题描述】:

我已经看到了很多(代码高尔夫)Perl 程序,即使我看不懂它们(不懂 Perl)我想知道你是如何设法获得这么少的代码来做什么的在其他一些编程语言中会占用 20 行代码。

  • Perl 的秘密是什么?是否有一种特殊的语法可以让您在几次击键中完成复杂的任务?是正则表达式的混合吗?

我想学习如何编写功能强大且简短的程序,就像您在此处的代码高尔夫挑战中所知道的那样。最好的起点是什么?我不想学习“干净”的 Perl - 我想写脚本,即使一周后我再也看不懂了

如果有其他编程语言可以用来编写更短的代码,请告诉我。

【问题讨论】:

  • 尽管有人可能会想知道目标——“我想写脚本,即使一周后我不再理解”——这是一个完全合理且可以回答的问题。它应该重新打开。一个好的答案会注意到诸如(a)来自系统管理员、sed、awk 文化的 Perl 的历史; (b) Perl 使用特殊变量和运行选项来促进在 Unix 管道上下文中开发单行脚本; (c) Perl 的默认参数$_;可能还有其他一些东西。
  • 关闭的原因是“无法客观地回答这个问题;这种类型的问题太开放了,通常会导致对抗和争论。”关于“对抗和争论”的部分完全是虚假的——这个问题不会导致对抗和争论。我已经投票决定重新开放。如果您想关闭某些东西,请出于真实原因关闭它。
  • @Kinopiko:好的,好吧,cwiki?它显然没有一个正确的答案。
  • 我认为这应该是社区维基
  • 我不同意。 “Perl 的哪些特性使它如此适合打高尔夫球?”显然确实有客观正确(即“正确”)的答案。

标签: perl obfuscation


【解决方案1】:

有许多因素使 Perl 适合打代码:

  • 没有数据输入。值可以作为字符串和数字互换使用。
  • “对角线”语法。通常称为 TMTOWTDI(有不止一种方法。)
  • 默认变量。如果没有指定参数,大多数函数都作用于$_。 (几个动作 在@_。)
  • 采用多个参数的函数(如split)通常具有以下默认值 让你省略一些参数,甚至全部省略。
  • “神奇”的 readline 运算符,<>
  • mapgrep这样的高阶函数
  • 正则表达式被集成到语法中(即不是一个单独的库)
  • 短路运算符返回最后测试的值。
  • 短路运算符可用于流量控制。

此外,没有限制(默认情况下是关闭的):

  • 您不需要声明变量。
  • Barewords 自动引用到字符串。
  • undef 变为 0'',具体取决于上下文。

既然已经不碍事了,让我说清楚一点:

高尔夫是一种游戏。

渴望达到让你擅长的 perl-fu 水平很棒,但以$DIETY 的名义,不要打真正的代码。一方面,这是一种可怕的浪费时间。您可能会花一个小时尝试修剪掉几个字符。打高尔夫球的代码很脆弱:它几乎总是做出重大假设,并且轻率地忽略错误检查。真正的代码不能这么粗心。最后,作为程序员,您的目标应该是编写清晰、健壮且可维护的代码。编程中有句谚语:始终编写代码,就好像维护它的人是一个知道你住在哪里的暴力反社会者。

所以,无论如何,开始打高尔夫球吧;但要意识到它只是在玩玩,然后就这样对待它。

【讨论】:

  • 优秀的答案。我也有这种感觉,Perl 对列表的定位可能对打高尔夫球很有用,但我不确定,也不知道如何表达它。
  • Perl 有数据类型。它只是不需要程序员告诉 Perl 类型是什么——假设程序员会保持它们的正确性。
  • 乔恩几乎是对的。 Perl 是非常强类型的。标量是标量,数组是数组,散列是散列。您不能更改变量的类型。它只是不会尝试进一步划分您放入标量的内容。这只是一个单一的价值。然而,Perl 确实在幕后跟踪标量值的字符串、整数和浮点版本。
【解决方案2】:

大多数人都忽略了 Perl 的大部分语法和默认操作符。 Perl 在很大程度上是一种“DWIM”(按照我的意思)语言。它的主要设计目标之一是“让普通的事情变得简单,让困难的事情成为可能”。

作为其中的一部分,Perl 设计人员谈论语法的 Huffman 编码,并考虑人们需要做什么,而不是仅仅提供低级原语。你经常做的事情应该需要最少的输入,函数应该像最常见的行为一样。这样可以节省不少工作量。

例如,split 有许多默认值,因为在某些用例中,不做任何事情会使用常见情况。在没有参数的情况下,split 在空格上拆分 $_,因为这是一个非常常见的用法。

 my @bits = split;

一种不太常见但仍然常见的情况是将$_ 拆分为其他内容,因此有一个稍长的版本:

 my @bits = split /:/;

而且,如果您想明确说明数据源,您也可以指定变量:

 my @bits = split /:/, $line;

按照您通常处理生活的方式来思考这个问题。如果您有一项经常执行的常见任务,例如与您的调酒师交谈,您可以使用它的简写来涵盖通常的情况:

平常

如果你需要做一些稍微不同的事情,你可以扩展一下:

通常,但加洋葱

但你总是可以注意细节

一杯肮脏的孟买蓝宝石马提尼酒,摇晃而不搅拌

下次浏览网站时请考虑一下。你做常用操作需要多少次点击?为什么有些网站易于使用而有些则不然?大多数时候,好的网站需要你做最少的工作来做常见的事情。不像我的银行需要不少于 13 次点击来支付信用卡账单。给他们钱应该很容易。 :)

【讨论】:

    【解决方案3】:

    这并没有回答 整个 的问题,但是关于编写代码你将无法在几天内阅读,这里有一些语言会鼓励你写得简短,几乎不可读的代码:

    【讨论】:

    【解决方案4】:

    Perl 有很多单字符特殊变量,它们提供了很多快捷方式,例如 $. $_ $@ $/ $1 等。我认为它与内置的正则表达式相结合,可以让你写一些非常简洁但不可读的代码。

    【讨论】:

      【解决方案5】:

      Perl 的special variables($_、$.、$/ 等)通常可用于使代码更短(并且更模糊)。

      【讨论】:

        【解决方案6】:

        我猜“秘密”在于为经常重复的任务提供本地操作。

        在 perl 最初为您设想的领域中,您经常不得不

        • 逐行输入
        • 去掉空格
        • 将线条转换成文字
        • 关联数据对
        • ...

        perl 提供了简单的操作符来做这些事情。短变量名称和许多事情的默认使用只是肉汁。

        perl 也不是第一种采用这种方式的语言。 perl 的许多功能或多或少是从 sed 和 awk 以及各种 shell 中窃取的(或通常略有改进)。对拉里有好处。

        当然 perl 不是最后一个采用这种方式的,你会在 python 和 php 和 ruby​​ 中找到类似的功能......人们喜欢结果并且不会为了获得更常规的语法而放弃它们.

        【讨论】:

          【解决方案7】:

          Java 只在一行中复制一个变量,而不用担心总线和内存的秘诀是什么?答:代码被转换为更大的代码。曾经发明的每一种语言都一样。

          【讨论】:

          • 我想知道 Perl 的语法是什么让你能够做到这一点
          • 是的……我就是这么回答的。
          • @Coronatus:不是真的。 “代码转换为更大的代码”不是语法属性。
          • 我的意思是 Perl 语法中的 what。不是为什么。例如:空格是可选的,有这个结构可以让你这样做,等等。
          • 这个答案是什么意思? “仅在一行中复制变量”?您是指通过垃圾收集的对象引用来管理内存吗? “担心公共汽车……”?除了为某些设备编写机器代码之外,还有谁呢? “转换为更大的代码”?在什么意义上?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-05
          • 2011-07-30
          • 1970-01-01
          • 2011-05-19
          • 2015-12-23
          • 1970-01-01
          相关资源
          最近更新 更多