in reply to Re: De-Overload reference?
in thread De-Overload reference?

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

Replies are listed 'Best First'.
Re^3: De-Overload reference?
by choroba (Cardinal) on Apr 17, 2024 at 08:29 UTC
    > 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

        No, I just showed it doesn't happen in threads. I have no expertise in Choro.

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

Re^3: De-Overload reference?
by NERDVANA (Priest) on Apr 17, 2024 at 18:50 UTC
    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

        Perl avoids concurrency at the global level using clones of all globals for each thread. You can still break things with XS though. I don't know if the cloning of globals extends down into the magic structures backing the 'overload' feature, but I'd consider it a bug if it didn't.