H4 has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks:

I'm trying to write a perl program which reads CSV files via the DBI interface. When I try to execute a SELECT statement ($dbh->prepare(...) then $sth->execute) I get the following error message:

Use of uninitialized value in substitution (s///) at <path_to_perl>/site/lib/Inline/Files/Virtual.pm line 120.

Obviously this is a side effect of Inline::Files which my program also uses.

Debugging into the execute() call, I believe that Inline::Files::Virtual::vf_open does not correctly handle the 3-parameters form of the open() call issued by IO::File::open which is called to open the csv file. However I don't quite understand why vf_open gets called at all, for something that is nothing like a DATA handle, nor do I understand the code in vf_open, so I am not sure whether this is a bug, and what I can do about it.

Any thoughts?

Replies are listed 'Best First'.
Re: Inline::Files and DBD::CSV
by JavaFan (Canon) on Oct 14, 2008 at 11:41 UTC
    vf_open is called because Inline::Files redefines CORE::GLOBAL::open.

    Perhaps your best option is to not use Inline::Files. Ever since I saw Brian Ingerson and Damian Conway present this at YAPC in Montreal, I've been of the opinion that the module is a nice trick, but not something I'd ever use in any serious program. Many of Damians modules don't work nice with other code - and this is another example. (But that's generally the case if you use source filters, add stuff in UNIVERSAL:: or overwrite core functions - you're bound to do something you didn't anticipate someone else does).

        Categorized Damian Modules... that's what the world was waiting for :-)
Re: Inline::Files and DBD::CSV
by ikegami (Patriarch) on Oct 14, 2008 at 16:08 UTC
    Instead of Inline::Files, you could use something like:
    open(my $fh, '<', \<<'__EOI__'); ... ... ... __EOI__

    A more complex example:

    my %files = ( users => <<'__EOI__', ... ... ... __EOI__ posts => <<'__EOI__', ... ... ... __EOI__ ); open(my $fh_users, '<', \$files{users}); open(my $fh_posts, '<', \$files{posts});
      Now that I'm aware that Inline::Files was not meant to be used in production code, I'll think up something like what you suggest... maybe a bit more sophisticated because I want to keep all the data towards the end of file (that's why I used Inline::Files in the first place). Anyway, thanks for the help!
        Just do
        my %file; init_files(\%files); . . . sub init_files { my ($files) = @_; %$files = ( ... ); }