The problem is on returning the value from getNumUsers(), the tied FETCH method is already being called. What I want is to delay this until, say, the later print statement, when the value is actually being used, rather than just being passed. I guess the solution is somehow detecting, within the FETCH, whether it's just being passed or whether the value is actually being used. Something like;package lazydbvalue; use strict; use Carp; sub TIESCALAR { # $sth is a prepared DBI statement handle my ($class, $sth) = @_; my $self = {}; $self->{sth} = $sth; bless ($self, $class); return $self; } sub FETCH { my $self = shift; $self->{sth}->execute(); my $row = $self->{sth}->fetchrow_arrayref; $self->{sth}->finish(); return $row->[0]; } sub STORE { my ($self, $sth) = @_; croak('STORE not supported - read only'); } sub DESTROY { my $self = shift; undef $self->{sth}; } package main; use strict; use DBI; # Returns the "lazy" tied scalar sub getNumUsers { my $dbh = shift; my $sth = $dbh->prepare('SELECT COUNT(*) FROM users'); tie my $numUsers, 'lazydbvalue', $sth; return $numUsers; } # Connect to DB etc., assiging connection to $dbh; my $numUsers = getNumUsers($dbh); print "Number of users: $numUsers\n";
Something similar wantarray I guess - knowing the calling context. Many thanks.sub FETCH { my $self = shift; # Just passing... if ( justPassingTheValue() ) { return $self; } # Value is being used in some expression # Now evaluate the real thing... $self->{sth}->execute(); my $row = $self->{sth}->fetchrow_arrayref; $self->{sth}->finish(); return $row->[0]; }
In reply to Delay evaluation of tied scalar when returned from sub by harryf
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |