最近Stack Overflow上有一群讨厌perl的人,所以我想我应该把我的“关于你最喜欢的语言你讨厌的五件事”的问题带到Stack Overflow上。拿你最喜欢的语言来说,告诉我你讨厌它的五件事。这些可能只是让你烦恼的事情,承认的设计缺陷,公认的性能问题,或任何其他类别。你只需要讨厌它,它必须是你最喜欢的语言。

不要拿它和其他语言比较,也不要谈论你已经讨厌的语言。不要用你最喜欢的语言谈论你喜欢的事情。我只是想听到你讨厌但能容忍的东西,这样你就可以使用所有其他的东西,我想听到你希望别人使用的语言。

每当有人试图把他们最喜欢的语言强加给我时,我就会问这个问题,有时是面试问题。如果有人找不出他最喜欢的工具的5个缺点,那他对它还不够了解,不能提倡它,也不能利用它赚大钱。他还没有在足够多的不同情况下使用它来充分探索它。他把它作为一种文化或宗教来倡导,这意味着如果我不选择他最喜欢的技术,我就错了。

我不在乎你用什么语言。不想使用特定的语言?那就不要。你通过尽职调查做出了明智的选择,但仍然没有使用它?好吧。有时正确的答案是“你有一个强大的编程团队,有良好的实践和丰富的Bar经验。改成Foo是愚蠢的。”


This is a good question for code reviews too. People who really know a codebase will have all sorts of suggestions for it, and those who don't know it so well have non-specific complaints. I ask things like "If you could start over on this project, what would you do differently?" In this fantasy land, users and programmers get to complain about anything and everything they don't like. "I want a better interface", "I want to separate the model from the view", "I'd use this module instead of this other one", "I'd rename this set of methods", or whatever they really don't like about the current situation. That's how I get a handle on how much a particular developer knows about the codebase. It's also a clue about how much of the programmer's ego is tied up in what he's telling me.

憎恨并不是衡量人们了解多少的唯一尺度,但我发现它是一个相当不错的尺度。他们讨厌的事情也让我知道他们对这个话题的思考有多好。


当前回答

按最讨厌到最不讨厌的顺序排列。

1.) Backwards compatibility police. Yes backcompat is a strength but Perl 5 takes it too far. Now we don't really even get new features in our language without having to enable them explicitly. I'm much prefer the inverse, if a new feature causes a problem let me disable it or enforce old behavior. e.g. perl 5.10 added say I'd rather have no feature 'say' if I have my own say implemented than have to put use feature 'say'; or use 5.010; also if 5.8 worked but 5.10 didn't. I'd rather have use 5.008; to restrict my code to only use features available up to and including 5.8 if no use version; was defined then it should be defaulted to whatever version you're running, and a recommended practice of not to restrict it unless you have to.

2)。过度的样板。

#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use autodie;
use English '-no_match_vars';
use 5.010;
package Package::Name;

BEGIN {
    Package::Name::VERSION = 0.1;
}

sub somesub {
    my $self = shift;
    my ( $param1, $param2 ) = @_;
}
1;

现在你可以开始编码了。这不会因为第一条而改变。当然也有一些捷径,比如使用common::sense;或者使用modern::perl;这将缩短上面的内容,你可能需要一些稍微不同的模块或pragma。但因为第一条,我们永远无法把它降低到。

#!/usr/bin/perl
package Package::Name 0.01;

sub somesub ( $param1, $param2 ) {
}

一些模块正在帮助这一点,在5.0.12中有新的包版本,它完全允许这种语法,尽管我认为它需要使用5.012;首先,和Method::签名,但它永远不会完全解决,(在语言)。

3)。糟糕的变量选择

吸吸文件

#!/usr/bin/perl
use strict;
use warnings;
open my $fh, "< foo" or die $!;
local $/; # enable localized slurp mode
my $content = <$fh>;
close $fh;

WTF是$!和美元/ ?重写为易读。

#!/usr/bin/perl
use strict;
use warnings;
use English '-no_match_vars';
open my $fh, "< foo" or die $ERRNO;
local $INPUT_RECORD_SEPARATOR; # enable localized slurp mode
my $content = <$fh>;
close $fh;

不要忘记,如果您不想受到性能影响,'-no_match_vars'必须存在。

不直接创建匿名标量怎么样?

#!/usr/bin/perl
my $scalar_ref = \do{ my $anon_scalar };

他们就不能想出点什么办法吗?

#!/usr/bin/perl
my $scalar_ref = <>;

哦,perl是线程不友好的,因为所有的变量(包括特殊的变量)默认是全局的。至少现在你可以使用我的$_;对其词法作用域,并对其他词使用local。

4.)非常难看的语法

MooseX::Declare是一个更好的语法。我也希望->被替换为。(个人喜好不太重要)

5)。太多的TIMTOWTDI或太多的最佳实践似乎你必须读3-5本书才能弄清楚你应该如何做事情。

6)。以前的(不再适用)。Un-sane版本。5.10.0有新功能5.10.1的新功能没有设定时间,直到下一个版本。现在是每年一次的特性发布,每季度更新一次。

7)。象牙塔视角。社区问题,似乎是许多开发者想要设置更高的准入门槛,并认为可以不尊重n00b(或任何不同意他们的人)。

8)。疯狂的版本号/字符串Perl有浮点版本号,它们很难看。开发人员不知道并不是所有的下游处理版本比较的方式都是一样的。不是语言问题

0.012 # simple
5.012001 # semantic 
4.101900 # time based + version (for multiple versions in a day)
0.035_002 # prerelease

所有有效版本的perl..我们就不能用…

0.12 # simple
5.12.1 # semantic
20100713 # time based (just use the date and be careful not to need to release more than 1 a day)
0.35-beta2 # prerelease

除了

9)。升级后没有明显的方法重新安装所有XS模块

其他回答

再给c++投一票…仍然是我最喜欢的语言,有几个亲密的追随者——C和Python。以下是我目前最讨厌的名单,排名不分先后:

Plethora of integer types inherited from C - way too many problems caused by signed vs. unsigned mistakes Copy constructors and assignment operators - why can't the compiler create one from the other automatically? Variable argument madness - va_list just doesn't work with objects and I'm so sick of problems created with sprintf(), snprintf(), vsnprintf(), and all of their relatives. Template implementation is required to be fully visible at compile time - I'm thinking of the lack of "export" implementations or at least usable ones Lack of support for properties - I want to have a read-only member like "a.x" that can be read publicly and only assigned internally. I really hate the "val=obj.getX()" and "obj.setX(val)". I really want properties with access control and a consistent syntax.

Perl

我喜欢这门语言,我不想添加已经被使用过的东西,但还没有人提到过这一点,所以我就把它扔到锅上。当我使用这个特性时,我发现这是我一生中最可怕的经历(而且我用过汇编语言):

write()和format()函数。

它们的语法是最糟糕、最丑陋、最可怕的,但是它们并没有提供比printf()更好的功能更多的功能。任何人都不应该尝试使用这两个函数进行任何输出,因为它们有多糟糕。

我相信有人会不同意,但是当我研究它们,希望它们能解决我的问题时,我发现它们是一个“痛苦的世界”(引用Big Lebowski的话),我希望Perl6已经消除了它们,或者更好的是完全重写它们,使它们在某种程度上更可用和有用。

Python:

缺少静态类型 默认参数处理(特别是可以为未来的调用者更改默认参数的事实!) 需要的下划线太多(构造函数必须调用__init__) 缺少适当的私有成员和函数(惯例只是说大多数以下划线开头的东西都是私有的,除了像__getattr__这样的东西不是) 有趣的打印到文件的语法(但他们在Python 3中修复了这个问题)

闲聊

我不想再用java、delphi、c#或ruby进行开发(这是不切实际的,因为我公司的主要开发语言是c#、delphi和java)。 从左到右的评估。 有类注释但没有方法注释(至少在Squeak中) 没有真正的标准库,在细节上有很多差异 缺少名称空间

Lua:

I understand the reasons, but seriously. Variables should be local by default, with a global keyword, not vice versa. I'm in general not a huge fan of the do/end style semantics. I much prefer C-style braces. Dynamic typing. I know, some of you go "Huh?" but I've been entirely spoiled by knowing exactly what type of data will be in a given variable. Constant if (type(var) == "string") then stuff() end is a pain. Variables need not be defined before they're used. I would much rather be explicit about what I'm trying to do than risk a typo causing what I like to call "wacky beans".

PHP:

同样,动态类型。 缺少闭包。你可以用$function($arg);但这不算。 同样,变量可以在定义之前使用。我有一个个人策略,总是在使用任何变量之前显式地将其初始化为已知值,并且我将其扩展到我可以控制的任何最佳实践文档。

C / C + +:

头疼=脖子疼。 不支持闭包。(我对c++ 0x很兴奋,因为c++ 0x有这些功能。) 静态类型。“等等,”你说。“你刚才说你不喜欢动态类型!”是的,我确实这么说过。但是静态类型也会让人头疼。(如果有选择的话,我仍然会选择静态类型。)最理想的情况是,我希望语言默认是静态类型的,但也支持动态类型。(我还想要一匹小马,500亿美元,还有整个世界。)