【发布时间】:2017-06-18 23:00:40
【问题描述】:
我正在编写一个带有多个参数的子例程。这些参数中的大多数都是标准的按值传递排序,在子例程中对它们所做的更改在子例程之外无关紧要。但是其中一个是一个对象(祝福引用),如果它被传入,我想对其进行更改,它在子例程之外可用。如果它没有传入,我想实例化它并同样对待它就好像它被传入(但最终返回)一样。
例如:
my $foo = Private::Foo->new();
# $foo->{'something'} eq 'old value'
Private::Foo->do_things('abc', 'xyz', $foo);
# $foo->{'something'} eq 'new value'
my $foo2 = Private::Foo->do_things('def');
# $foo2->{'something'} eq 'old value'
package Private::Foo;
# ...
sub do_things {
my ($self, $arg1, $arg2, $foo) = @_;
unless (defined $foo) {
$foo = Private::Foo->new();
}
if ($arg1 eq 'abc') {
$foo->{'something'} = 'new value';
return;
}
return $foo;
}
我希望使用尽可能简洁的语法来执行此操作,并且可以使用 Perl v5.22 及更高版本中提供的任何功能。 (我试图弄清楚如何使用refaliasing 做到这一点,但它不是很干净。)
我错过了什么?
【问题讨论】:
-
关于“我错过了什么?”,什么都没有。您的代码按原样运行。
-
Re "大部分参数都是标准的按值传递排序",Perl 总是通过引用传递。例如,
perl -e'sub f { $_[0] = "def"; } my $x = "abc"; f($x); CORE::say $x;'输出def。 -
呸,你说得对,这似乎确实有效。我之前尝试的一些事情组合给了我错误;我猜他们是无关的。另外,我所说的“按值传递”是标准
my ($foo) = @_,在我的示例(而不是您的示例)中,它立即出现在子例程的开头。 -
在收到参数后复制参数并不会改变它们通过引用传递的事实。你复制了一个论点这一事实并不能阻止你改变论点。