Hi, Have searched around for an answer to this without success - could be I'm searching for the wrong thing but anyway... I'm trying to delay evaluation of a tied scalar to the point where it is actually used in some expression, and not just passed between subroutines. When evaluated, it's actually making a call to a database, and I'm trying to delay this call to the very last moment (e.g. when it's used in a print statement). Easiest to explain in code I guess, which looks something like this...
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";
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;
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]; }
Something similar wantarray I guess - knowing the calling context. Many thanks.

In reply to Delay evaluation of tied scalar when returned from sub by harryf

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.