我的所有变量都以my $var
格式声明。
在我的程序中,我叫mainMethod()
然后在mainMethod
中定义一个DateTime变量,然后将其传递给单独的辅助方法3次。:
my ($day,$month,$year)=(localtime)[3,4,5];
my $dt = DateTime->new(
year => $year,
month => 2 + $month,
day => 1,
hour => 8,
minute => 30,
time_zone => 'America/New_York'
);
helper($dt, $year, $month, $day,);
helper($dt,$year, $month, $day,);
helper($dt,$year, $month, $day,);
在helper
中,我从以下位置开始:
my $date = $_[0];
my ($year, $month, $day) = ($_[1],$_[2],$_[3]);
[此方法做了很多不同的事情,但我对$date
所做的唯一更改是$date = $date->add(days => (3 - $date->day_of_week) % 7);
问题是,似乎我在辅助方法中进行的$date
更改在每次从mainMethod
调用该方法时都会持续存在,注意:我什么都不返回
例如,如果$dt
改为5
而helper
等于$date + 2
,我会得到
helper($dt) #output: 7
helper($dt) #output: 9
helper($dt) #output: 11
而不是每个响应预期的5。
在方法结束时是否缺少一些步骤来重置这些变量?
[DateTime
创建一个reference。
因此,当您调用helper($dt)
时,会将引用的副本传递给helper
。它不会创建一个全新的DateTime对象。
对传递的值所做的任何更改都会对已经创建的单个DateTime对象进行。
如果要创建三个不同的DateTime对象,则需要调用DateTime->new
3次。
这与范围界定无关。您的DateTime对象是一个引用。这就是对象在Perl中的工作方式。
为了解释正在发生的事情,我将使用一个更简单的数据结构。数组引用的工作方式相同。
my $foo = [];
helper($foo);
print "@$foo\n";
helper($foo);
print "@$foo\n";
helper($foo);
print "@$foo\n";
sub helper {
my $bar = $_[0];
push @$bar, 1;
}
此程序的输出为
1
1 1
1 1 1
就像您的DateTime对象一样,我们正在传递对helper()
函数的引用。像这样传递标量值将创建一个副本,但是由于变量仅包含对内存中其他位置的引用,因此它将复制该[[pointer。它仍将指向内存中的同一位置,因此您对此所做的任何更改都将反映在原始DateTime对象中。