I find it very handy to store perl structures in a file for later use (via Data::Dumper).

I also find it useful to belss structures into object classes.

I found that DB_File, when using $DB_RECNO, will store array elements into a nice, flat text file - one per line.

This is great stuff, and infinitely useful. I decided to try to tie this all together (literally), so that I could do something like this:

$db = tie @tie, ...., $DB_RECNO; $db->filter_fetch_value( sub { $_ = eval } ); while($tie[0]->timestamp < time - 3600) { shift @tie; }
However, while this works fine with methods which are defined in a given class, it does not work with AUTOLOAD. Furthermore, the code does not fail with a runtime error (i.e. "method not found"), but silently returns undef. This bothered me greatly (because I hadn't figured out it was AUTOLOAD yet). So I did some testing:
foreach $rec (@tie) { my $x = $rec; print "timestamp1: ", $rec->timestamp, "\n"; print "timestamp2: ", $x->timestamp, "\n"; }
I found that the copy works fine, but the initial reference is somehow unable to return values via the AUTOLOAD method (the return value is always undef). Then I did this and was quite surprised:
foreach $rec (@tie) { my $x = $rec; print "rec: $rec, x: $x\n"; }
I found that the two seemingly equal references are not equal, that is:
$x = $rec; print $x == $rec ? "match\n" : "differ\n"; # always returns 'differ'
When the references are printed, they have different addresses in memory. However, when dumped via Data::Dumper, they are EXACTLY the same. They are both belss()-ed into the correct package, and even show identical key ordering.

I am very confused about this behavior. 'perlref' implies that this copy of references should result in the same reference in both variables, and that $x == $rec should be true.

In the mean time, I've defined all of my accessor methods statically and bypassed AUTOLOAD alltogeher, but this is not very clean and is not very portable. What if I dump an object from a class that I didn't create which uses AUTOLOAD? I have no recourse other than to copy every returned reference. This severely limits the usefulness of  $db->filter_fetch_value( sub { $_ = eval } ) and the wonderful $tie[$x]->method() behavior it (supposedly) allows...

I wonder if someone might help me understand what is happenging here...

- Darrin


In reply to A problem with eval via DB_File->filter_fetch_value() and AUTOLOAD by dgorski

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.