package # hide from PAUSE indexer / CPAN indexing
    Devel::WatchVars::Tie::Scalar;

use utf8;
use strict;
use warnings;
no overloading;

our $VERSION = v1.0.0;

(my $PKG = __PACKAGE__) =~ s/::Tie::Scalar//;

use Carp qw(shortmess);

push our @CARP_NOT => $PKG, qw(
    Data::Dump 
    Data::Dumper
);

use Devel::GlobalDestruction;

sub mycarp {
    local $\;
    print STDERR &mymess;
}

sub mymess {
    local $Carp::Verbose;
    return &shortmess;
}

sub redef($) {
    return $_[0] // "undef";
}

use namespace::clean;

###########################################################

sub TIESCALAR {
    my($class, $name, $value) = @_;
    unless ($name) {
        $name = mymess "some scalar variable";
        $name =~ s/ at (\S.*) (line \d+)[.]?\n\z/ watched at $2 of $1/;
    }
    mycarp "WATCH $name = ", redef $value;
    return bless {
        name  => $name,
        value => $value,
    }, $class;
}

sub FETCH {
    my($self) = @_;
    mycarp "FETCH $$self{name} --> ", redef $$self{value};
    return $$self{value};
}

sub STORE {
    my($self, $new_value) = @_;
    mycarp "STORE $$self{name} <-- ", redef $new_value;
    return $$self{value} = $new_value;
}

sub DESTROY {
    my($self) = @_;
    my $action =
          in_global_destruction                      ? "DESTROY (during global destruction)"
        : ((caller 2)[3] // "") eq "${PKG}::unwatch" ? "UNWATCH"
        :                                              "DESTROY";
    mycarp "$action $$self{name} = ", redef $$self{value};
    if (my $sref = $$self{sref}) {
          $$sref = $$self{value} unless in_global_destruction;
    } 
    delete @$self{keys %$self};
}

1;
