1IO::Detect(3) User Contributed Perl Documentation IO::Detect(3)
2
3
4
6 IO::Detect - is this a frickin' filehandle or what?!
7
9 use IO::Detect;
10
11 if (is_filehandle $fh)
12 {
13 my $line = <$fh>;
14 }
15
17 It is stupidly complicated to detect whether a given scalar is a
18 filehandle (or something filehandle like) in Perl. This module attempts
19 to do so, but probably falls short in some cases. The primary advantage
20 of using this module is that it gives you somebody to blame (me) if
21 your code can't detect a filehandle.
22
23 The main use case for IO::Detect is for when you are writing functions
24 and you want to allow the caller to pass a file as an argument without
25 being fussy as to whether they pass a file name or a file handle.
26
27 Functions
28 Each function takes a single argument, or if called with no argument,
29 operates on $_.
30
31 "is_filehandle $thing"
32 Theoretically returns true if and only if $thing is a file handle,
33 or may be treated as a filehandle. That includes blessed references
34 to filehandles, things that inherit from IO::Handle, etc.
35
36 It's never going to work 100%. What Perl allows you to use as a
37 filehandle is mysterious and somewhat context-dependent, as the
38 following code illustrates.
39
40 my $fh = "STD" . "OUT";
41 print $fh "Hello World!\n";
42
43 "is_filename $thing"
44 Returns true if $thing is a IO::All object or Path::Class::Entity
45 or "any non-reference, non-zero-length string with no line breaks".
46 That's because depending on your operating system, virtually
47 anything can be used as a filename. (In fact, on many systems,
48 including Linux, filenames can contain line breaks. However, this
49 is unlikely to be intentional.)
50
51 This function doesn't tell you whether $thing is an existing file
52 on your system. It attempts to tell you whether $thing could
53 possibly be a filename on some system somewhere.
54
55 "is_fileuri $thing"
56 Returns true if $thing is a URI beginning with "file://". It allows
57 for URI objects, RDF::Trine::Node::Resource objects, strings and
58 objects that overload stringification.
59
60 This function actually returns an "interesting value of true". The
61 value returned is a URI::file object.
62
63 "as_filehandle $thing, $mode"
64 Returns $thing if it is a filehandle; otherwise opens it with mode
65 $mode (croaking if it cannot be opened). $mode defaults to "<"
66 (read access).
67
68 This function is not exported by default, but needs to be requested
69 explicitly:
70
71 use IO::Detect qw(as_filehandle);
72
73 You may even specify a different default mode, or import it several
74 times with different names:
75
76 use IO::Detect
77 as_filehandle => { -as => 'as_filehandle_read', mode => '<' },
78 as_filehandle => { -as => 'as_filehandle_write', mode => '>' };
79
80 Smart Matching
81 You can import three constants for use in smart matching:
82
83 use IO::Detect -smartmatch;
84
85 These constants are:
86
87 "FileHandle"
88 "FileName"
89 "FileUri"
90
91 They can be used like this:
92
93 if ($file ~~ FileHandle)
94 {
95 ...
96 }
97
98 Note that there does exist a FileHandle package in Perl core. This
99 module attempts to do the right thing so that "FileHandle->new" still
100 works, but there are conceivably places this could go wrong, or be
101 plain old confusing.
102
103 Although "is_filehandle" and its friends support Perl 5.8 and above,
104 smart match is only available in Perl 5.10 onwards.
105
106 Use with Scalar::Does
107 The smart match constants can also be used with Scalar::Does:
108
109 if (does $file, FileHandle)
110 {
111 ...;
112 }
113 elsif (does $file, FileName)
114 {
115 ...;
116 }
117
118 Precedence
119 Because there is some overlap/ambiguity between what is a filehandle
120 and what is a filename, etc, if you need to detect between them, I
121 recommend checking "is_filehandle" first, then "is_fileuri" and falling
122 back to "is_filename".
123
124 for ($file)
125 {
126 when (FileHandle) { ... }
127 when (FileUri) { ... }
128 when (FileName) { ... }
129 default { die "$file is not a file!" }
130 }
131
132 Export
133 Like Scalar::Does, IO::Detect plays some tricks with namespace::clean
134 to ensure that any functions it exports to your namespace are cleaned
135 up when you're finished with them.
136
137 Duck Typing
138
139 In some cases you might be happy to accept something less than a
140 complete file handle. In this case you can import a customised "duck
141 type" test...
142
143 use IO::Detect
144 -default,
145 ducktype => {
146 -as => 'is_slurpable',
147 methods => [qw(getlines close)],
148 };
149
150 sub do_something_with_a_file
151 {
152 my $f = shift;
153 if ( is_filehandle $f or is_slurpable $f )
154 { ... }
155 elsif ( is_filename $f )
156 { ... }
157 }
158
159 Duck type test functions only test that the argument is blessed and can
160 do all of the specified methods. They don't test any other aspect of
161 "filehandliness".
162
164 Please report any bugs to
165 <http://rt.cpan.org/Dist/Display.html?Queue=IO-Detect>.
166
168 This module is an attempt to capture some of the wisdom from this
169 PerlMonks thread <http://www.perlmonks.org/?node_id=980665> into
170 executable code.
171
172 Various other modules that may be of interest, in no particular
173 order... Scalar::Does, Scalar::Util, FileHandle, IO::Handle,
174 IO::Handle::Util, IO::All, Path::Class, URI::file.
175
177 Toby Inkster <tobyink@cpan.org>.
178
180 This software is copyright (c) 2012-2014, 2017 by Toby Inkster.
181
182 This is free software; you can redistribute it and/or modify it under
183 the same terms as the Perl 5 programming language system itself.
184
186 THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
187 WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
188 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
189
190
191
192perl v5.36.0 2023-01-20 IO::Detect(3)