use Loop::Watch;
my $x = 2;
ensure { $x > 0 } watching($x), doing {
# all your code centered around $x here
};
####
package Tie::Scalar::Watch;
use Carp;
use strict;
# rich man's Exporter ;)
# this just puts 'watch()' in the caller's namespace
sub import {
my $pkg = caller;
no strict 'refs';
*{ $pkg . "::watch" } = \&watch;
}
sub TIESCALAR {
my ($class, $val, $rule) = @_;
my $self = bless [ undef, $rule ], $class;
$self->STORE($val);
return $self;
}
sub FETCH { $_[0][0] }
sub STORE {
my ($self, $val) = @_;
return $self->[0] = $val if $self->[1]->($val);
croak "Value $val is out of bounds";
}
sub watch (&$) {
tie $_[1], __PACKAGE__, $_[1], $_[0];
}
1;
####
use Tie::Scalar::Watch; # imports 'watch'
my $x = 10;
watch { $_[0] > 5 } $x;
# $x is now transparently tied!
# and you thought tying was transparent already!
while (1) {
print "$x\n";
$x--;
}
####
sub STORE {
my ($self, $val) = @_;
$self->[0] = $val;
$self->[1]->() ?
return $val :
croak "Value $val is out of bounds";
}