为什么我的Perl功能不起作用?

时间:2009-04-11 17:09:17

标签: perl function pass-by-reference

我在编写函数时遇到问题......

sub TemplateReplace
{
    my($regex, $replacement, $text) = @_;
    $text =~ s/($regex)/($replacement)/gs;
}

my $text = "This is a test.";
TemplateReplace("test", "banana", $text);

但它不起作用。我认为参数是在Perl中通过引用发送的。行my($regex, $replacement, $text) = @_;然后复制它们吗?我该如何解决这个问题?

4 个答案:

答案 0 :(得分:10)

sub TemplateReplace
{
   my($regex, $replacement, $text) = @_;
   $text =~ s/($regex)/($replacement)/gs;
   return $text;
}

 my $text = "This is a test.";
 $text = TemplateReplace("test", "banana", $text);

有。这应该有用。

是的,你的我的(..)= @_确实复制了args。因此,如果您要修改变量,则需要将其返回,除非它是全局变量。

答案 1 :(得分:8)

您正在修改传入的$text的副本;这对原版没有影响。

#!/usr/bin/perl

use strict;
use warnings;

my $text = "This is a test.";

template_replace(qr/test/, "bannana", $text);

print "$text\n";

sub template_replace {
    my $regex       = shift;
    my $replacement = shift;
    $_[0] =~ s/$regex/$replacement/gs;
}

上面的代码是有效的,因为@_的元素是传入的变量的别名。但是Adnan的答案是更常见的。修改传递给函数的参数是令人惊讶的行为,并使template_replace(qr/foo/, "bar", "foo is foo")之类的东西无效。

答案 2 :(得分:4)

这是制作数据副本的子程序的“赋值”部分。

如果直接修改@_参数,它们可以按预期工作。然而,它不是非常易读。 : - )

use strict;
umask(0);
$|=1;
my $debug = 0;

my $text = "This is a test.";

print "Before 1: [$text]\n";
TemplateReplace("test", "banana", $text);
print "After 1: [$text]\n";

print "Before 2: [$text]\n";
TemplateReplace2("test", "banana", $text);
print "After 2: [$text]\n";

sub TemplateReplace
   {
   my ($regex, $replacement, $text) = @_;    

   $text =~ s/($regex)/($replacement)/gs;
   }

sub TemplateReplace2
   {
   $_[2] =~ s/$_[0]/$_[1]/gs;
   }

返回:

Before 1: [This is a test.]
After 1: [This is a test.]
Before 2: [This is a test.]
After 2: [This is a banana.]

答案 3 :(得分:0)

以下是有关如何操作的变体,这与您的代码几乎完全相同,但略有不同。

use strict;
use warnings;


sub TemplateReplace {
    my($regex, $replacement, $text) = @_;
    $$text =~ s/($regex)/$replacement/gs;
}



my $text = "This  is a test."; 
TemplateReplace("test", "banana", \$text);
print $text;

此行为是显式而非隐式。在实践中,它与Chas. Owens结果的工作方式相同,但使用标量引用而不是依赖于理解数组的行为。

这将使任何阅读代码的人更明显地看到函数“TemplateReplace”故意修改$ text。

此外,它会通过以下方式告诉您使用它的错误:

Can't use string ("This  is a test.") as a SCALAR ref while "strict refs" in use at replace.pl line 9.

如果你碰巧忘记了\某个地方。