4

我写的函数有问题...

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

4 回答 4

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);

那里。那应该行得通。

是的,你的 my( ..) = @_ 确实复制了参数。所以如果你正在修改一个变量,你需要返回它,除非它是一个全局变量。

于 2009-04-11T17:16:02.690 回答
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")不起作用。

于 2009-04-11T17:30:40.333 回答
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.]
于 2009-04-11T17:29:42.457 回答
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。

此外,它会告诉你用 squawking 错误地使用它:

在 replace.pl 第 9 行使用“严格引用”时,不能使用字符串(“这是一个测试。”)作为 SCALAR 引用。

如果你碰巧忘记了 \ 某处。

于 2009-04-12T19:01:15.770 回答