in reply to You can't get there from here....
in thread References of Eternal Peril

The problem that I have with hashes is that you go through all of the work in strict to make sure you cannot mistype your variable names and then you throw it all away because there is no check for misspelled hash entries.

I have used 2 solutions to get around that in the past. One is Class::Struct, the other is pseudo-hashes. Each has their gotchas. Now I know you had some bad luck with pseudo-hashes in the Topaz effort, which leads me to a couple of questions.

First of all what do you suggest to this problem? (Want to use a hash or reference to one, but with only validated keys allowed.)

And secondly is it likely that stuff I did with pseudo-hashes is going to be low priority (ie in the 5% acceptable breakage) for Perl 5.6? (I know it is early for this question, I just would like an educated guess.)

Thanks,
Ben

Replies are listed 'Best First'.
RE: RE: You can't get there from here....
by chip (Curate) on Aug 11, 2000 at 06:17 UTC
    Plan A: Put a unique prefix on the database column names, turning off strict temporarily:
    { no strict 'refs'; $sth->bind_columns( map { \${"c_$_"} @{ $sth->{NAMES_lc} } ) }
    Plan B: If you want the advantages of variables and the advantages of hashes, there is a way, but it will cost you a little in speed. There is one language construct that can see variables and can be built with strings, even with strict enabled: eval.
    local $, = ',$'; # saves on the joins eval "\$sth->bind_columns(\\( \$@{$sth->{NAMES_lc}} ))"
    However, now you're actually letting column names into the Perl parser! A saying about frying pans and fires comes to mind.... I'd much rather disable strict than make wide use of eval STRING.

    As for pseudohashes: I think they're great. The only thing about their implementation in Perl 5 that ate me alive was the fact that they weren't a distinct data type, but rather a mere access method, usable with any array at any time. If they had to be declared somehow at their creation, hey, I'd have been praising them in my Topaz talk.

        -- Chip Salzenberg, Free-Floating Agent of Chaos

      I really like merlyn's idea of a tied hash. I will check CPAN for that, else make it myself. I may just make its internal representation look like a pseudohash though. :-)

      Personally I would prefer the syntax of a pseudohash if it needed some sort of declaration, IMO it is too bad that the technical advantages of that interface was not realized earlier. :-(

      chip, merlyn, and tilly (and anyone else, I suppose):

      Some of the ideas listed here set me to thinking. What would be the implications of creating a separate package just for the row data and using that instead of a hash? That is pretty much what I am doing now, except referencing main:: instead of another symbol table.

      Some things I am concerned about:

      • Memory usage in creation a second package in a perl program
      • Speed of calling variables longhand from other packages (ie, $Foo::Bar::zot)
      • Anything in a similar, pragmatic vein... :-)

      If you folks think it's feasible, I'll generate a couple thousand records of junk data and do some benchmarks this weekend.

      Alakaboo

        That makes the variable name collision less likely, but what if you pick a package name someone else is using? (If your code ends up in a module somewhere and someone else uses it, there's a possibility.) Plus, it means your template variable references will require package name prefixes. (I suppose you could also put a package statement and the templating sections within a block.)

        I doubt it's as efficient as just using the fetch hashref method, but I don't have numbers to back that up. You'll still have potential typos to deal with (in your template), and symbolic references (for little gain, in my opinion), and you'll have to write more documentation on what's going on (and hopefully why) for yourself and future potential maintainers.

        I don't think this technique is going to save you anything over the method DBI already provides, in the long run.

RE: RE: You can't get there from here....
by merlyn (Sage) on Aug 11, 2000 at 05:59 UTC
    As a runtime solution, create a tied hash that supported only a limited set of keys, throwing an exception if a distinct key was used.

    -- Randal L. Schwartz, Perl hacker