gpt4 book ai didi

perl - 重载 Perl 对象以将哈希访问重定向到自定义例程

转载 作者:行者123 更新时间:2023-12-01 09:42:27 25 4
gpt4 key购买 nike

不久前,我编写了一个例程,它解析给定的字符串并以散列(field => value, field2 => value2) 的形式返回记录。很好,除了要求发生了变化,我现在需要返回更多数据并提供 getter 方法来获取这些数据。因此,我调整了例程以返回一个 Record 对象,该对象将相同的哈希存储在 data 属性中。

但是,这会破坏需要散列的旧代码,以便它可以使用 $record->{field} 获取数据。使用新的 Record 对象,该数据的路径现在是 $record->{data}->{field}$record->getByShortName('字段').

我的想法是重载对象的 FETCH 方法并返回相应的字段。但是,这似乎不起作用。看起来从未调用过 FETCH。

我正在寻找三个建议:

  1. 如何正确重载我的对象,以便将哈希访问尝试重定向到对象的自定义方法?
  2. 这是一种可取的工作方式还是会大大降低速度?
  3. 在我的情况下,是否有更好的方法来保持向后兼容性?

这是一个 MVE:

Record.pm

package Record;

use strict;
use warnings;
use Data::Dumper;
use overload fallback => 1, '%{}' => \&access_hash;

sub new {
my ($class, %args) = @_;
my %fields = (answer => 42, question => 21);
$args{fields} = \%fields;
return bless { %args }, $class;
}

sub access_hash {
my ($self) = shift;
return $self; # cannot return $self->{fields} because that would recurse ad infinitum
}

sub FETCH {
print(Dumper(@_)); # does not return anything, is this method not being called
}

test.pl

use Record;

my $inst = Record->new();

print($inst->{answer}."\n");
print($inst->{question}."\n");

最佳答案

Record 是一个受祝福的哈希引用,因此如果您重载 %{} 运算符,您将无法访问底层哈希的字段。

overload 作者考虑了这一点,并提供了 overloading pragma 作为禁用此用例和其他一些用例的重载的方法。

use overload '%{}' => \&access_hash;
...
sub access_hash {
no overloading '%{}';
my ($self) = shift;
return $self->{fields};
}

在 Perl 5.10 之前,解决方法是通过暂时将对象重新赋予不会激活重载运算符的对象来禁用重载。

sub access_hash {
my ($self) = shift;
my $orig_ref = ref($self);
bless $self, "#$%^&*()";
my $fields = $self->{fields};
bless $self, $orig_ref;
return $fields;
}

关于perl - 重载 Perl 对象以将哈希访问重定向到自定义例程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58065366/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com