Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

Is there any way to override "file test operator"?

by Anonymous Monk
on Aug 09, 2011 at 01:57 UTC ( #919359=perlquestion: print w/replies, xml ) Need Help??

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

Hello, Monks!

Is there any way to override "file test operator", using package?

I mean -X one -

if (-e($file_name)) {}

It's more than easy to override lot of over functions, using "sub FUNCTION_NAME { }" inside package, but i have no idea what sub name I could use to override "file test operator"? (it's even hard to name correctly here, to ask that question).

Any reply would be welcome, so I could at least stop searching.

Replies are listed 'Best First'.
Re: Is there any way to override "file test operator"?
by kejohm (Hermit) on Aug 09, 2011 at 02:38 UTC

    You can overload the operator with the overload pragma, although this only works if your package is being used as a class. Also only works on Perl v5.12 or later. Example:

    package MyFileTest; use overload ( '-X' => \&myfiletest, ); sub new { ... } ... package main; my $file = MyFileTest->new($filename); if(-f $file){ ... }

    See also the filetest pragma.

      Hmm, then this should also work, but it doesn't
      #!/usr/bin/perl -- BEGIN { use IO::File; package IO::Handle; use overload '-X' => sub { warn 'abracadabra'; stat@_; }; *IO::Handle::stat = sub { warn "hi walter"; stat(@_); }; } open my($fh), '<', __FILE__; print '-e ', -e $fh, "\n"; print '-f ', -f $fh, "\n"; print '-d ', -d $fh, "\n"; print 'stat ', stat $fh, "\n"; print $fh, "\n"; close $fh; print "$_\n" for keys %INC; __END__ -e 1 -f 1 -d stat 00332061000745131287651313128765131312876169 GLOB(0x3f8adc) warnings/ IO/ IO/ File/Spec/ File/ IO/ File/Spec/
Re: Is there any way to override "file test operator"?
by Marshall (Canon) on Aug 09, 2011 at 02:31 UTC

    if (-e($file_name)) {};
    Trying to override the -e file test is not what I would consider "smart". Even if you could, this is a bad idea.

    What other meaning would you have the "-e" do? And why would it make sense in the code?

      And I - as a simple bystander - would read that as

      if ( - e ($filename)) { ^

      that is "the negative value returned by the function e with argument $filename".

      Enjoy, Have FUN! H.Merijn
        #!usr/bin/perl -w use strict; my $file = 'C:\temp\'; if ( -e $file) { print "$file EXISTS!\n"; } print "$0 \n"; if ( - e $file) #this does not work! { print "$file WILD!\n"; } __END__ Can't locate object method "e" via package "C:\temp\" (perhaps you forgot to load "C:\temp\"?) at C:\TEMP\ line 13. C:\temp\ EXISTS! C:\TEMP\
      Even if you could, this is a bad idea.
      Such a blanket statement, without knowing the reasons of the OP needs at least some justification to be taken seriously.
      Why can't the OP decide to make a smarter file test operator? Maybe instrument it, or log something, or count gumdrops? Or maybe he has a new file system idea, where there are virtual files, and they only show up with special juju magic? Or an evil twin has renamed some files with a specific pattern, and the code needs to test for both possibilities?

      Sure, outside of that, it's probably not a good idea.

      Quantum Mechanics: The dreams stuff is made of

        I read back through this thread. Now that I see it again, the question appears to be "how can I make new file test operator?".
        I don't know how to do that.

        Overriding an existing file operator (like: -e $filename) is very bad idea. I stick to that opinion. The issue is when I see a line like that in some huge amount of code, I expect -e to do what it normally does without having to read any previous code that redefined that operation. And BTW, I don't know how to redefine -e either.

        In this case, I would make a subroutine that did the desired test and use that. In terms of execution efficiency, I see no difference. In terms of source code, there would be a huge increase in clarity.

Re: Is there any way to override "file test operator"?
by JavaFan (Canon) on Aug 09, 2011 at 08:24 UTC
    I don't think you can, at least not on a pure Perl level. If you're willing to write -E, or - e, you can write a subroutine named E or e, which then will be called instead (and of whose return value unary minus will be applied).
Re: Is there any way to override "file test operator"?
by Anonymous Monk on Aug 09, 2011 at 08:09 UTC

    Um, why would you even want to do this? You want to lie to your program about whether a file exists or not? Without some pretty specific and esoteric reasons, that just sounds silly

      One use I could see for this would be filenames that refer to a virtual file system. For example -f 'smb://server/share/' or -r 'ssh:user@host:some/file' could be resource tests that make sense if you want to provide a different syntax than just local filenames.

      Another use-case is for testing, e.g. I have a test script that detects whether bash exists using -x "/bin/bash". I'd like to be able to simulate the absence of bash by returning false to that expression even though /bin/bash is actually on my filesystem.
      Another use case is implementing support for symlinks on Windows. See Win32::Links for a situation where someone has taken the effort to do so, and could use a means of supporting -l to make it seamless.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://919359]
Approved by Old_Gray_Bear
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (6)
As of 2021-04-16 07:39 GMT
Find Nodes?
    Voting Booth?

    No recent polls found