Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

2shortplanks (968)

2shortplanks
  (email not shown publicly)
http://2shortplanks.com/
AOL IM: trelane2sp (Add Buddy, Send Message)
Yahoo! ID: trelane2sp (Add User, Send Message)

Mark Fowler has never been the same since he was elected leader of the London Perl Mongers. The strain manifests itself mainly in releasing various [cpan.org] modules [cpan.org] to CPAN, giving talks [2shortplanks.com], and use of the Trelane nick on #london.pm for endless procrastination. Doctors are still seeking a cure.
Friday June 28, 2002
06:11 AM

Slap Dash FileCache

[ #6037 ]
So I need to open a vast number of files. No problem I think to myself, I'll use the FileCache module. So I run my maketry script (which spits out a file with a "#!/usr/bin/perl" line at the top, turns strict and warnings on, and loads a load of standard modules like File::Spec and IO::File and friends, before loading it up in vi) and type (well cut and paste) out the example from the perl cookbook.

$path = "bar";

use FileCache;
cacheout ($path);         # each time you use a filehandle
print $path "output";

And it falls over with the wonderful error message:

Can't use string ("bar") as a symbol ref while "strict refs" in use at
filecache line 22.

So I spend ages trying to work out why the code isn't replacing $path with a ref to a filehandle like it should and it's leaving a bare string in there. I post to London.pm. I ask on IRC. I'm stumped...and then I look at the source. Of course! So FileCache doesn't create reference as store them in $path. It opens a filehandle in the calling package with the same name as the $path. This means that $path in the print statement is treated as a symbolic reference for a variable name and finds the right filehandle.

Okay, this is quite neat, but really really dangerous. use strict quite rightly barfs all over the place when I do this and I have to turn it off.

So it looks like I'm going to have to write my own module. Anyone got any better suggestions? Alternative modules on CPAN to do this?

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • DIY (Score:2, Insightful)

    So, fix the module and send the patch to the author.

    And if she isn't responsive, upload the new version yourself!

  • Umm this is really no different than if you took
    FileCache out of the picture, string filehandles
    just don't work under strict refs. They're
    essentially a form of symbolic reference, if
    you know what you're doing it's perfectly
    reasonable to run with no strict 'refs'.

    PS> I patched FileCache for perl 5.8, which still
    has this "problem", but more features. If you
    don't want to get all of 5.8 you can retrieve the
    module from ftp://pthbb.org/pub/pm/FileCache/ [pthbb.org]

    Enjoy
    --
    Were that I say, pancakes?
    • Excellent. This is what I love about Perl - if you waffle on about something for long enough you'll always find someone has already had a go at fixing it ;-)

      As for running without use strict, I'm not sure I trust myself that much ;-) I guess I could just turn it off lexically for the tight loop, but I get really worried about flicking the safety off the loaded gun pointing at my feet.

      Anyway, I've been busy since I posted my journal - I had a go at implementing my own modified version of FileCache whic

      • Not no strict, just no strict refs.

        I'll consider addng a line to the CAVEATS about absolute paths. It's really somehting the user should just keep in mind, again I think of FileCache (not that I am the oringal author) as simply an abstraction over open. It has one sole purpose and is not to catch every tiny faux pas the user might commit ;-)

        As for the roll-over, that wouldn't be an issue. So the file gets closed, and then might soon be reopened. If you look closely, the hash element is deleted when the

        --
        Were that I say, pancakes?
        • Not no strict, just no strict refs.

          Good point. Should have thought about that a bit more.

          I think of FileCache (not that I am the oringal author) as simply an abstraction over open.

          Yeah, though if I use open to open a second file with the same name from a different directory then it opens a different file. FileCache will use the first file it opened.

          However, I don't think I can think of any way to work around this with the current method of creating filehandles in the parent's namespace which

          • An IV (int) will roll over to an NV (double) at overflow point..

            While ++ will not then have exactly the same semantics, it will keep the value increasing, and not have the "random" effect you describe.
            • So does that mean that a ++ will potentially increase the value by more than one, until we reach +inf?

              Interesting - does this mean that ++ and += 1 are not always the same operation?

              • ++ and += 1 are always different ops, try perl -MO=Terse -e '$foo++; $bar += 1;' and note the ops used

                ++ gets folded to PP(preinc) which will do a simple ++SvIVX(sv) if it's a clean IV
                If it's not it calls sv_inc(sv) which does checks for magic and, if the value is an NV, performs SvNVX(sv) += 1.0;. How long the sv retains a value like a tight-jawed integer will be dependant on the implementation of the floating point code

      • If it were to be released for general consumption
        I think a better name would be IO::FileCache.

        One could also subclass FileCache to provide the
        rel2abs masking.
        --
        Were that I say, pancakes?
        • I was thinking more IO::HandleCache. Strictly, I'm dealing with handles not files now - it also avoids confusion with the depricated File::Cache module.


          I need to tidy everything up a bit first and maybe run some benchmarks.


          Fun.

          • It's FileCache not File::Cache.,
            and it isn't exactly caching files
            either. IO::FileCache highlights
            the relationship.
            --
            Were that I say, pancakes?
            • See! It is confusing. I was talking about the File::Cache [cpan.org] module that's been replaced by Cache::Cache.
              • Umm, except that's not CORE now is?
                And you did say CORE earlier, no? :-P

                And what do you mean you were talking
                about? You've been talking about
                cacheout, that's in FileCache...
                --
                Were that I say, pancakes?