我应该使用Perl的哪些动态编程功能?

时间:2010-09-01 21:34:24

标签: c++ c perl

我对scipting语言(特别是Perl)很陌生,我编写的大部分代码都是将C代码转换为Perl的无意识的努力。

  

Reading about Perl,其中一个经常被提到的最大区别是Perl是一种动态语言。因此,它可以在运行时执行其他语言(静态)只能在编译时执行的操作,因此可以更好地处理它,因为它可以访问实时信息。

所有这一切都没关系,但是我应该具备哪些特定功能,在C和C ++中有一些经验,在使用Perl编写代码时要记住它使用它拥有的所有动态编程功能,以产生一些非常棒的代码?

9 个答案:

答案 0 :(得分:15)

这个问题足以填满一本书。事实上,这正是发生的事情!

Mark Jason Dominus的优秀高阶Perl免费available online

这是引言,当我第一次阅读这本书时,它的口吻真的抓住了我的喉咙:

  

1993年左右,我开始读书   关于Lisp,我发现了一些东西   重要的是:Perl更像是Lisp   比它更像C.如果你拿起一个   关于Lisp的好书,会有一个   描述Lisp好的部分   特征。例如,这本书   人工智能的范式   编程由Peter Norvig撰写,包括   一个名为What Makes Lisp的部分   不同?这描述了七个   Lisp的功能。 Perl分享了六个   这些功能; C没有人分享。   这些都是重要的重要特征,   像一流的功能,   动态访问符号表,   和自动存储管理。

答案 1 :(得分:10)

不会延续到Perl 5中的C习惯列表:

  • 不要将变量声明在程序/函数的顶部。在需要时声明它们。
  • 在声明数组和散列时,不要将空列表分配给数组和散列(它们已经为空并且需要初始化)。
  • 请勿使用if (!(complex logical statement)) {},这是unless的用途。
  • 不要使用goto打破深层嵌套循环,nextlastredo都会将循环标签作为参数。
  • 不要使用全局变量(这是C的一般规则,但我发现很多C人都喜欢使用全局变量)。
  • 不要创建闭包将执行的函数(特别是回调)。有关详细信息,请参阅perldoc perlsubperldoc perlref
  • 不要使用输入/输出返回,而是返回多个值。

在Perl 5中可以做的事情:

  • 始终使用strictwarnings pragma。
  • 阅读文档(perldoc perlperldoc -f function_name)。
  • 使用哈希,就像在C中使用structs一样。

答案 2 :(得分:10)

通过可维护性,开发时间,可测试性和灵活性的最佳组合,使用可解决问题的功能。在特定应用程序的上下文之外讨论任何技术,样式或库都不是很有用。

您的目标不应该是找到解决方案的问题。学习Perl比你计划立即使用(并继续学习)。有一天你会遇到一个问题并且想“我记得有些东西可能有助于此”。

您可能希望看到其中一些内容,但是:

  • 高阶Perl
  • 掌握Perl
  • 有效的Perl编程

我建议您慢慢地逐步将新概念引入编码中。 Perl的设计使您不必了解很多内容,但您可以在了解更多信息的同时改进代码。试图同时掌握许多新功能通常会让你在其他方面遇到麻烦。

答案 3 :(得分:6)

我认为最大的障碍不是动态方面,而是“电池包含”方面。

我认为perl最强大的方面是

  • 哈希:它们可以让您轻松表达非常有效的数据结构
  • 正则表达式:它们非常完整。
  • 使用默认变量,如$ _
  • 未安装标准的库和CPAN

我注意到C转换的东西是过度使用for循环。可以使用 grep 地图

删除许多内容

perl的另一个座右铭是“有不止一种方法可以做到”。为了攀登学习曲线,你必须经常告诉自己:“必须有更好的方法来做到这一点,我不能成为第一个想做的人......”。然后,您通常可以通过其数量众多的库转向谷歌和CPAN。

perl的学习曲线并不陡峭,但它很长......慢慢来,享受骑行。

答案 4 :(得分:3)

两点。

首先,一般来说,我认为你应该问自己2个略有不同的问题:

1)Perl的哪些动态编程功能可用于哪些情况/解决哪些问题?

2)每个功能的权衡,缺陷和缺点是什么。

然后,您的问题的答案变得非常明显:您应该使用比同类非DP解决方案更好地解决您的问题的功能(性能或代码可维护性明智),并且导致低于最大可接受的下行水平

作为一个例子,引用FM的评论,eval的字符串形式有一些相当讨厌的缺点;但在某些情况下,它可能是一个非常优雅的解决方案,比任何备用DP或SP方法都要好几个数量级。


其次,请注意Perl的许多“动态编程”功能实际上已经打包成非常有用的模块,您甚至可能认为这些模块不具备DP性质。

我将不得不考虑一组很好的例子,但我们想到的是一个文本模板模块,其中许多是使用上面提到的eval字符串形式实现的;或者Try :: Tiny异常机制,它使用eval的块形式。

另一个例子是可以通过Moose实现的方面编程(我现在找不到相关的StackOverflow链接 - 如果有人请它在链接中编辑) - 下面使用访问符号表的功能DP。

答案 5 :(得分:2)

答案 6 :(得分:1)

至少IME,“动态”性质并不是那么重要。我认为您需要考虑的最大区别是,在C或C ++中,您大多习惯于使用库代码只有相当次要优势。库中的内容已经编写和调试,所以它很方便,但是如果推动一下,你通常可以自己做同样的事情。为了提高效率,这主要是一个问题,即你写一些更专业的东西的能力是否超过了图书馆作者花更多时间来完善每个例程的能力。然而,没有足够的差别,除非图书馆例程真正做到你想要的,否则你最好自己编写。

使用Perl,这已不再适用。 (巨大,与C相比)库中的大部分内容实际上是用C语言编写的。尝试自己编写任何非常相似的东西(当然,除非你编写C模块)不可避免地会出现相当慢的问题。因此,如果您可以找到一个甚至可以接近您想要的库例程,那么最好使用它。使用预先编写的库代码很多比在C或C ++中更重要。

答案 7 :(得分:1)

良好的编程习惯并非针对个别语言。它们适用于所有语言。从长远来看,您可能会发现最好依赖于动态语言中的技巧(例如,可以返回整数或文本值的函数),因为它会使代码更难以维护和快速了解。最后,为了回答你的问题,我不认为你应该寻找特定于动态类型语言的功能,除非你有一些令人信服的理由需要它们。保持简单易维护 - 从长远来看,这将更有价值。

答案 8 :(得分:-2)

只有动态语言可以做很多事情,但最酷的是eval。有关详细信息,请参阅here

使用eval,您可以像执行预先编写的命令一样执行字符串。您还可以在运行时按名称访问变量。

例如,

$Double = "print (\$Ord1 * 2);";

$Opd1 = 8;
eval $Double;  # Prints 8*2 =>16.

$Opd1 = 7;
eval $Double;  # Prints 7*2 =>14.

变量$Double是一个字符串,但我们可以执行它,因为它是一个常规语句。这不能用C / C ++完成。

很酷的是,字符串可以在运行时进行操作;因此,我们可以在运行时创建一个命令。

# string concatenation of operand and operator is done before eval (calculate) and then print.
$Cmd = "print (eval (\"(\$Ord1 \".\$Opr.\" \$Ord2)\"));";

$Opr  = "*";
$Ord1 = "5";
$Ord1 = "2";

eval $Cmd;  # Prints 5*2 => 10.

$Ord1 = 3;
eval $Cmd;  # Prints 5*3 => 15.

$Opr = "+";
eval $Cmd;  # Prints 5+3 => 8.

eval是非常强大的(如在蜘蛛侠中)权力伴随着责任。明智地使用它。

希望这有帮助。