如何在 Perl 中创建只读 DateTime 和 DateTime::Duration

发布于 2024-11-19 17:42:10 字数 926 浏览 1 评论 0原文

我有一个 Perl 脚本,尝试将一些已配置的 DateTimeDateTime::Duration 实例设置为 Readonly 常量。但当我尝试对这些对象进行数学计算时,如果它们是只读的,我会看到奇怪的行为。这是一个最小的示例:

#!/usr/bin/perl -w

use strict;
use warnings;

use DateTime;
use Readonly;

Readonly my $X => DateTime->now;
my $x = DateTime->now;

Readonly my $Y => DateTime::Duration->new( days => 3 );
my $y = DateTime::Duration->new( days => 3 );

my $a = $X - $Y;
my $b = $x - $y;

print "$a\n";
print "$b\n";

在我的系统(OSX 上的 Perl 5.10.0)上显示:

$ ./datetime_test.pl 
Argument "2011-07-12T20:36:08" isn't numeric in subtraction (-) at ./datetime_test.pl line 15.
-4305941629
2011-07-09T20:36:08

所以它看起来像制作 DateTimeDateTime::Duration Readonly 导致它们无法正常工作。这是一个错误吗?或者我使用Readonly错误?我还尝试过 Readonly::Scalar 和 Readonly::Scalar1 ,两者的行为方式相同。

I have a Perl script that's trying to set some configured DateTime and DateTime::Duration instances as Readonly constants. But I see strange behavior when trying to do math on these objects if they are Readonly. Here's a minimal example:

#!/usr/bin/perl -w

use strict;
use warnings;

use DateTime;
use Readonly;

Readonly my $X => DateTime->now;
my $x = DateTime->now;

Readonly my $Y => DateTime::Duration->new( days => 3 );
my $y = DateTime::Duration->new( days => 3 );

my $a = $X - $Y;
my $b = $x - $y;

print "$a\n";
print "$b\n";

On my system (Perl 5.10.0 on OSX) this displays:

$ ./datetime_test.pl 
Argument "2011-07-12T20:36:08" isn't numeric in subtraction (-) at ./datetime_test.pl line 15.
-4305941629
2011-07-09T20:36:08

So it looks like making the DateTime and the DateTime::Duration Readonly causes them to function incorrectly. Is this a bug? Or am I using Readonly wrong? I've also tried Readonly::Scalar and Readonly::Scalar1, and both behave the same way.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笑,眼淚并存 2024-11-26 17:42:10

问题在于它们是对象(引用),而不是普通标量。您需要只读引用中包含的值,而不是引用本身;但事实证明这很棘手。像这样的东西似乎有效:

use Readonly;
use DateTime;

# you can't just say "Readonly %$dt"; here at least, it dies on blessed refs
sub makeRO {
  my $dt = shift;
  while (my ($k, $v) = each %$dt) {
    Readonly $dt->{$k} => $v;
  }
}

my $x = DateTime::Duration->new(days => 3);
makeRO($x);
my $y = DateTime::Duration->new(days => 3);

my $a = $x - $y;
# print "$a\n"; # this isn't overloaded; you'll get "DateTime::Duration=HASH(...)"
print $a->days, "\n";

The problem is that they're objects (references), not normal scalars. You would need to Readonly the values contained in the references, not the references themselves; but this turns out to be tricky. Something like this appears to work:

use Readonly;
use DateTime;

# you can't just say "Readonly %$dt"; here at least, it dies on blessed refs
sub makeRO {
  my $dt = shift;
  while (my ($k, $v) = each %$dt) {
    Readonly $dt->{$k} => $v;
  }
}

my $x = DateTime::Duration->new(days => 3);
makeRO($x);
my $y = DateTime::Duration->new(days => 3);

my $a = $x - $y;
# print "$a\n"; # this isn't overloaded; you'll get "DateTime::Duration=HASH(...)"
print $a->days, "\n";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文