这个琐碎的功能傻了吗?

Cha*_*ens 4 perl

我今天遇到了一个让我停下来思考的功能.我想不出有这么好的理由:

sub replace_string {
        my $string  = shift;
        my $regex   = shift;
        my $replace = shift;

        $string =~ s/$regex/$replace/gi;

        return $string;
}
Run Code Online (Sandbox Code Playgroud)

我能看到的唯一可能的值是,它使您能够控制替换使用的默认选项,但我认为没有用.看到这个函数后,我的第一反应就是"这是做什么的?".一旦我了解它的作用,我就会假设从那时起就做到了.这意味着如果它发生变化,它将破坏我需要它的任何代码.这意味着该功能可能永远不会改变,或者更改它会破坏大量代码.

现在我想追踪原来的程序员,并在他或她身上打败一些感觉.这是一个有效的愿望,还是我错过了这个功能带来的一些价值?

Sch*_*ern 11

该功能的问题包括:

  • 不透明:replace_string并没有告诉您,您正在进行不区分大小写的全局替换而不进行转义.
  • 非惯用语:$string =~ s{$this}{$that}gi你可以学习它曾经意味着什么,它不像它的一些奇怪的角落特征. replace_string每个人都必须了解其中的每一个细节,并且每个人都会有所不同.
  • 不灵活:想要非全球性的搜索和替换?抱歉.您可以通过传入一些修饰符,qr//但这比s///其隐藏的知识要高得多.
  • 不安全:用户可能认为该函数采用字符串,而不是正则表达式.如果他们放入未经检查的用户输入,他们就会打开一个潜在的安全漏洞.
  • 更慢:只是添加最后的侮辱.

优点是:

  • Literate:函数名称解释了它的作用,而不必检查正则表达式的细节(但它给出了一个不完整的解释).
  • 默认值:默认值gi默认值始终存在(但名称不明显).
  • 更简单的语法:不必担心分隔符(不是那么s{}{}困难).
  • 免受全球副作用:正则表达式匹配设置全局变量(沙拉$1,$+等...),但它们会自动局部范围的功能.如果你将它们用于另一个正则表达式,它们不会干涉.

封装有点过分热心.

  • @George =>添加一个函数调用,它的相关堆栈操作,从堆栈中移出参数......所有这些都为替换添加了恒定的时间.由于替换通常多次执行,因此开销可能会增加. (3认同)
  • 由于将字符串复制到`$ string`和`return $ string`,@ George和字符串长度的线性时间. (2认同)

Bil*_*hor 5

print replace_string("some/path", "/", ":");
Run Code Online (Sandbox Code Playgroud)

是的,你可以在不必更换/使用不同的分隔符或在正则表达式中转义/获得一些魔力.


Mic*_*man 5

如果它只是一个冗长的替代品,s///那么我猜它是由某人从一种使用正则表达式需要额外语法的语言来到Perl的人编写的,而且这种方式更适合编码.如果是这样的话,我会将它归类为Perl baby-talk:对经验丰富的程序员来说傻乎乎的尴尬但不坏 - 不过还不足以保证殴打,无论如何.;)

如果我真的很眯眼,我几乎可以看到这样一个函数可能有用的情况:将一堆模式应用于一堆字符串,允许用户输入条款,为回调提供CODE引用...

  • 他们应该因为没有在匹配字符串上运行quotemeta而受到殴打...... (4认同)
  • @Eric:这是包装函数如何危险的一个很好的例子 - 它们让用户误认为已经考虑了"边缘"情况,而实际上它们并没有被考虑过. (2认同)
  • 一个天真的`quotemeta`并没有好多少.它应该测试`$ regex`是否是一个`qr //`编译的模式,并且仅当它不是时才应用`quotemeta`.以太的观点:虽然可能存在虚假的安全感,但也有一个地方可以解决问题. (2认同)