in reply to De-Overload reference?

If you have a blessed hashref that overloads hashref access, I would think the best way to handle it is change the type of reference you are blessing, or switch to inside-out attributes.
perl -E ' use v5.36; use overload q{%{}} => sub { { foo => 1 } }; sub foo { $_[0]->$*->{foo} } my $x= bless \{ foo => 2 }, "main"; say $x->foo; '
perl -E ' use v5.36; use Scalar::Util "refaddr"; use overload q{%{}} => sub { { foo => 1 } }; our %attrs; sub new { my $self= bless {}, shift; $attrs{refaddr $self}= { @_ }; $s +elf } sub DESTROY { delete $attrs{refaddr $_[0]} } sub foo { $attrs{refaddr $_[0]}{foo} } my $x= main->new(foo => 2); say $x->foo; '

Replies are listed 'Best First'.
Re^2: De-Overload reference?
by LanX (Saint) on Apr 17, 2024 at 22:41 UTC
    Hmm ... inside outs are an option, forgot about them. Thanks. :)

    But is there a reason why you make %attr a package-var? I'd rather use a lexical closure var my %attr

    FWIW: Using a scalar-ref as object is clever, but in this case I'm overloading all deref-operators, hence we are back to the original problem.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

      But is there a reason why you make %attr a package-var?

      In case a sub-class wants to inspect (or extend) my fields. I'm in the opposite camp as Ovid.

Re^2: De-Overload reference?
by ikegami (Patriarch) on Apr 17, 2024 at 21:00 UTC

    What problem are you trying to fix?

    It appears you think the following is an example of the problem:

    use v5.36; use overload q{%{}} => sub { { foo => 1 } }; sub foo { $_[0]->{foo} } my $x= bless { foo => 2 }, "main"; say $x->foo;

    But there's no infinite loop in that program, and the OP asks how to avoid an infinite loop.

    [choroba's answer has the same problem, I think.]

    I wish the OP would have provided a demo the problem and stated what they were trying to achieve.

      The code you posted here (without the hash-ref-ref) returns '1', and the code I posted returns '2'.

      In other words, the problem here is that the method 'foo' is accessing the output of the overridden ref operator instead of the true value stored within the object. My example using a hash-ref-ref returns the true value from method foo.

      try to access $self->{foo} (to get the 2) INSIDE q{%{}} => sub { { foo => 1 } };

      I even had core dumps while trying to use Data::Dump::pp(\@_)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      see Wikisyntax for the Monastery