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と同じように機能します。オーエンスの結果ですが、配列の動作を理解することに依存する代わりに、scalar-refsを使用します。

これにより、コードを読んでいる人なら誰でも、関数「TemplateReplace」が意図的に$textを変更していることがわかりやすくなります。

さらに、次のようにしゃがむことで、間違って使用していることがわかります。

replace.plの9行目で「strictrefs」が使用されている間は、文字列(「これはテストです。」)をSCALAR参照として使用できません。

どこかで\を忘れてしまったら。

于 2009-04-12T19:01:15.770 に答える