Каков наилучший способ перегрузить перегрузку в аксессуре атрибута Moose?

У меня есть класс, где я хочу применить перегрузку строк в свой атрибут id. Тем не менее, Moose не разрешает перегрузку строк в ассемблерах атрибутов. Например:

package Foo;
use Moose;
use overload '""' => \&id, fallback => 1;
has 'id' => (
    is => 'ro',
    isa => 'Int',
    default => 5,
);

package main;
my $foo = Foo->new;
print "$foo\n";

Вышеприведенное даст ошибку:

You are overwriting a locally defined method (id) with an accessor at C:/perl/site/lib/Moose/Meta/Attribute.pm line 927

Я попробовал пару вариантов, чтобы обойти это:

  • Маркировка id is => bare и замена его моим собственным аксессуаром: sub id {$_[0]->{id}}. Но это всего лишь хак.

  • При использовании перегружателя строк используйте другой метод, который просто возвращает делегату id: sub to_string {$_[0]->id}.

Мне просто интересно, есть ли у кого лучший способ сделать это?

Ответ 1

use overload '""' => sub {shift->id}, fallback => 1;

Прекрасно работает для меня.

Ответ 2

Я полагаю, что вы получаете сообщение об ошибке, потому что \&id создает местозаполнитель для суб, который будет определен позже, потому что Perl должен будет знать адрес, который будет иметь sub, когда он определен, чтобы создать ссылку на него. У Moose есть свои собственные проверки, чтобы попытаться избежать методов перезаписи, которые вы определяете, и сообщает об этом вам.

Так как я думаю, что вы действительно хотите сделать, вызовите метод id, когда объект используется как жало, например:

use overload '""' => 'id', fallback => 1;

Из overload документации

Значения, указанные как строки, интерпретируются как имена методов.