As indicated by Tom Browder in this issue, the $*ARGFILES
dynamic variable might contain invalid filehandles if any of the files mentioned in the command line is not present.
for $*ARGFILES.handles -> $fh {
say $fh;
}
will fail with and X::AdHoc
exception (this should probably be improved too):
Failed to open file /home/jmerelo/Code/perl6/my-perl6-examples/args/no-file: No such file or directory
The problem will occur as soon as the invalid filehandle is used for anything. Would there be a way of checking if the filehandle is valid before incurring in an exception?
You can check if something is a Failure
by checking for truthiness or definedness without the Failure
throwing:
for $*ARGFILES.handles -> $fh {
say $fh if $fh; # check truthiness
.say with $fh; # check definedness + topicalization
}
If you still want to throw the Exception
that the Failure
encompasses, then you can just .throw
it.
TL;DR I thought Liz had it nailed but it seems like there's a bug or perhaps Ugh.
It looks like whenever the IO::CatHandle
class's .handles
method reaches a handle that ought by rights produce a Failure
(delaying any exception throw) it instead immediately throws an exception (perhaps the very one that would work if it were just delayed or perhaps something broken).
This seems either wrong or very wrong.
See the exchange between Zoffix and Brad Gilbert and Zoffix's answer to the question How should I handle Perl 6 $*ARGFILES that can't be read by lines()?
Also:
https://github.com/rakudo/rakudo/issues/1313
https://github.com/rakudo/rakudo/search?q=argfiles&type=Issues
https://github.com/rakudo/rakudo/search?q=cathandle&type=Issues
In discussing "Implement handler for failed open on IO::CatHandle"
Zoffix++ closed it with this code as a solution:
.say for ($*ARGFILES but role {
method next-handle {
loop {try return self.IO::CatHandle::next-handle}
}
})
I see that tbrowder has reopened this issue as part of the related issue this SO is about saying:
If this works, it would at least be a usable example for the
$*ARGFILES
var in the docs.
But when I run it in 6.d
(and see similar results for a 6.c
), with or without valid input, I get:
say not yet implemented
(similar if I .put
or whatever).
This is nuts and suggests something gutsy is getting messed up.
I've searched rt and gh/rakudo issues for "not yet implemented" and see no relevant matches.
Zoffix clearly intended their code as a permanent solution, not merely a workaround. But it unfortunately doesn't seem to work at all for now.
The best I've come up with so far:
try {$*ARGFILES} andthen say $_ # $_ is a defined ArgFiles instance
orelse say $!; # $! is an error encountered inside the `try`
Perhaps this works as a black-and-white it either all works or none of it does solution. (Though I'm not convinced it's even that.)
$*ARGFILES
$*ARGFILES
says it is an instance of
IO::ArgFiles
which is doc'd as a class which
exists for backwards compatibility reasons and provides no methods.
And
All the functionality is inherited from
IO::CatHandle
which is subtitled as
Use multiple IO handles as if they were one
and doc'd as a class that is
IO::Handle
which is subtitled as
Opened file or stream
and doc'd as a class that doesn't inherit from any other class (so defaults to inheriting from Any
) or do any role.
So, $*ARGFILES
is (exactly functionally the same as) a IO::CatHandle
object which is (a superset of the functionality of) an IO::Handle
object, specifically:
The
IO::CatHandle
class provides a means to create anIO::Handle
that seamlessly gathers input from multipleIO::Handle
andIO::Pipe
sources. All ofIO::Handle
's methods are implemented, and while attempt to use write methods will (currently) throw an exception, anIO::CatHandle
is usable anywhere a read-onlyIO::Handle
can be used.
IO::CatHandle
(To be filled in later?)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With