You could overload the stringify operator to get the current value of the object.
#!/usr/bin/perl -w
use strict;
package LazyBool;
use constant THE_BIT => 1 << 9;
use constant RAND_SIZE => 1 << 16;
use overload 'bool' => sub {
my $self = shift;
$self->{value}();
};
use overload q[""] => sub {
my $self = shift;
return defined $self->{peek}() ? $self->{peek}() : "not defined";
};
sub new {
my $class = shift;
my ($value,$self) = (undef,{});
$self->{value} = sub {
defined $value ?
$value :
$value = THE_BIT & rand(RAND_SIZE) ? 1 : 0;
};
$self->{peek} = sub {
$value;
};
bless $self, $class;
}
1;
package main;
use strict;
my $foo = LazyBool->new;
print "\$foo is $foo", $/;
print '$foo is true', $/ if $foo;
print "\$foo is $foo", $/;
It does essentially the same as your example code but just hides away the calls to
$foo->{peek}() in the stringify operator. It seems the logical way to do it as you'll only be 'looking' at the value of
$foo in a string context (well that's what
$peek seems to allude to). That's what
overloaded operators are for right?
HTH
broquaint