in reply to De-Overload reference?

Update: Old contents replaced.

I tried to use

overload->unimport('%{}');

It kind of works in the way it makes the reference available, but I can't make it overloaded again.

The same holds for

eval 'no overload'
.

It works, but I can't make the object overloaded back again.

Update 2:

I made it work nicely as I intended:

#!/usr/bin/perl use warnings; use strict; use feature qw{ say }; { package LanX; use overload '%{}' => \&_nothing, '""' => sub { $_[0]->_underload(\&_value) }; sub new { bless {value => $_[1]}, $_[0] } sub inc { $_[0]->_underload(sub { ++$_[0]->{value} }) } sub value { $_[0]->_underload(\&_value) } sub _nothing { { value => 'nothing' } } sub _value { $_[0]->{value} } sub _underload { my ($self, $sub) = @_; overload->unimport('%{}'); my $v = $self->$sub; overload->import('%{}' => \&_nothing); return $v } } my $l = 'LanX'->new(12); say "deref\t" => $l->{value}; # nothing say "l\t" => $l; # 12 say "deref\t" => $l->{value}; # nothing say "inc\t" => $l->inc; # 13 say "l\t" => $l; # 13 say "inc\t" => $l->inc; # 14 say "l\t" => $l; # 14 say "deref\t" => $l->{value}; # nothing

map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Replies are listed 'Best First'.
Re^2: De-Overload reference?
by LanX (Saint) on Apr 16, 2024 at 21:31 UTC
    Cool, thanks. Forgot about unimport.

    Tho I'm not sure if deactivated overload for the whole class doesn't bear the danger of a race condition with another instance in a parallel thread.

    I just had the idea to just temporarily bless this $self to another neutral class.

    There is also a tip in the docs I want to try out tomorrow.

    Thanks again :)

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

      > I'm not sure if deactivated overload for the whole class doesn't bear the danger of a race condition with another instance in a parallel thread.

      #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; use threads; use threads::shared; my $done :shared; my $t = 'threads'->create(sub { my %count; my $l2 = 'LanX'->new(42); # <- You can move this into the below l +oop, too. until ($done) { ++$count{ $l2->{value} }; } for my $key (keys %count) { say "$key: $count{$key}"; } }); { package LanX; use overload '%{}' => \&_nothing, '""' => sub { $_[0]->_underload(\&_value) }; sub new { bless {value => $_[1]}, $_[0] } sub inc { $_[0]->_underload(sub { ++$_[0]->{value} }) } sub value { $_[0]->_underload(\&_value) } sub _nothing { { value => 'nothing' } } sub _value { $_[0]->{value} } sub _underload { my ($self, $sub) = @_; overload->unimport('%{}'); my $v = $self->$sub; sleep 1 if 0 == threads->tid; overload->import('%{}' => \&_nothing); return $v } } my $l = 'LanX'->new(12); say "deref\t" => $l->{value}; # nothing say "l\t" => $l; # 12 say "deref\t" => $l->{value}; # nothing say "inc\t" => $l->inc; # 13 say "l\t" => $l; # 13 say "inc\t" => $l->inc; # 14 say "l\t" => $l; # 14 say "deref\t" => $l->{value}; # nothing $done = 1; $t->join;

      > the idea to just temporarily bless this $self to another neutral class

      Brilliant idea. Seems less ugly, but it's not 100% clear why it's there, so probably needs a comment or a good name for the class.

      sub _underload { my ($self, $sub) = @_; my $class = ref $self; bless $self, 'Cancel::LanX::So::We::Can::Dereference'; my $v = $self->$sub; sleep 1 if 0 == threads->tid; bless $self, $class; return $v }

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        Please excuse my ignorance, while there are multiple possible approaches for concurrency in Perl, including cpan solutions like Coro I'm not experienced with them.

        The race condition I'm worried about is that the overloading might be deactivated when in a simultaneous situation it's expected.

        Does your code prove this to be not possible?

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

        > bless $self, 'Cancel::LanX::...

        I always knew one day I'd be the target of cancel culture, but I didn't expect it coming from you ... ;-P

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

      I thought threads got their own copy of the interpreter. Do they share package stashes?
        Depends on the threads-modell and the OS, I suppose?

        And there are various other concurrency models...

        The package is practically a global variable, so only meddling with the object is already a much cleaner design.

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