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. | [reply] [Watch: Dir/Any] [d/l] |
|
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/register.pm
XSLoader.pm
IO/Handle.pm
SelectSaver.pm
IO/Seekable.pm
warnings.pm
Fcntl.pm
IO.pm
Symbol.pm
Carp.pm
File/Spec/Unix.pm
strict.pm
Exporter.pm
vars.pm
File/Spec.pm
IO/File.pm
overload.pm
File/Spec/Win32.pm
| [reply] [Watch: Dir/Any] [d/l] |
Re: Is there any way to override "file test operator"?
by Marshall (Canon) on Aug 09, 2011 at 02:31 UTC
|
WHAT?
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? | [reply] [Watch: Dir/Any] |
|
if ( - e ($filename)) {
^
that is "the negative value returned by the function e with argument $filename".
Enjoy, Have FUN! H.Merijn
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
#!usr/bin/perl -w
use strict;
my $file = 'C:\temp\test20.pl';
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\test20.pl"
(perhaps you forgot to load "C:\temp\test20.pl"?)
at C:\TEMP\test20.pl line 13.
C:\temp\test20.pl EXISTS!
C:\TEMP\test20.pl
| [reply] [Watch: Dir/Any] [d/l] |
|
|
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.
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |
|
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.
| [reply] [Watch: Dir/Any] |
|
|
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). | [reply] [Watch: Dir/Any] [d/l] [select] |
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
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
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.
| [reply] [Watch: Dir/Any] |
|
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.
| [reply] [Watch: Dir/Any] [d/l] |