#!/usr/bin/perl package Tie::Ensure; use strict; sub TIESCALAR { my ($class, $var, $code) = @_; bless { VAL => $$var, CODE => $code, }, $class; } sub FETCH { $_[0]{VAL} } sub STORE { my ($self, $val) = @_; local $_ = $self->{VAL} = $val; die "[Tie::Ensure]\n" unless $self->{CODE}->(); } package main; use strict; sub ensure (&@) { my ($cref, $obj, $loop) = @_; tied($$obj)->{CODE} = $cref; eval { { $loop->(); redo } }; die $@ if $@ ne "[Tie::Ensure]\n"; untie $$obj; } sub using (\$) { tie ${$_[0]}, 'Tie::Ensure', $_[0]; return $_[0]; } sub looping (&) { $_[0] } my $foo = 10; ensure { $_ < 15 } using($foo), looping { print "before: $foo\n"; $foo++; print "after: $foo\n"; };