On 7/5/2012 5:57 PM, Mark Overmeer wrote:
Show quoted text> * Chris Marshall (devel.chm.01@gmail.com) [120705 20:54]:
>>> my $data = try { Geo::KML->readFrom($file) };
>>> die $@ if $@;
>>
>> This is the first file IO routine that I have seen that kills perl
>> rather than returning some sort of status or exception.
>
> Traditional modules in Perl do not use exception mechanisms. If they
> have such mechanisms, than I expect they will also die on fatal exceptions
> which are not caught.
Correct, but the problem is that the current default
kills perl without the ability to recover. It is ok
for that to be the implementation you choose but it
needs to be documented so folks can work around the
death of the interpreter. The perl read builtin does
not die if it fails, just returns undef:
Show quoted text> read FILEHANDLE,SCALAR,LENGTH,OFFSET
> read FILEHANDLE,SCALAR,LENGTH
> Attempts to read LENGTH characters of data into variable SCALAR
> from the specified FILEHANDLE. Returns the number of
> characters actually read, 0 at end of file, or undef if there
> was an error (in the latter case $! is also set). SCALAR will
> be grown or shrunk so that the last character actually read is
> the last character of the scalar after the read.
>
> An OFFSET may be specified to place the read data at some place
> in the string other than the beginning. A negative OFFSET
> specifies placement at that many characters counting backwards
> from the end of the string. A positive OFFSET greater than the
> length of SCALAR results in the string being padded to the
> required size with "\0" bytes before the result of the read is
> appended.
>
> The call is actually implemented in terms of either Perl's or
> system's fread() call. To get a true read(2) system call, see
> "sysread".
>
> Note the characters: depending on the status of the filehandle,
> either (8-bit) bytes or characters are read. By default all
> filehandles operate on bytes, but for example if the filehandle
> has been opened with the ":utf8" I/O layer (see "open", and the
> "open" pragma, open), the I/O will operate on UTF-8 encoded
> Unicode characters, not bytes. Similarly for the ":encoding"
> pragma: in that case pretty much any characters can be read.
Show quoted text>> I saw nothing in the Geo::KML docs to suggest
>> that an eval is needed to keep perl alive after
>> trying to read a KML file. At the least, please
>> document your recommended usage so folks
>> will know the danger and how to work around
>> the problem.
>
> I do not see how people would be able to implement a generic
> work-around for file-formats which are not supported.
The problem isn't whether you can anticipate every
possible use of the modules, just that the current
implementation prevents any possible use outside
the scope you have envisioned.
In my case, if the file is bad, I can ask for another
file. At the least, I would like the perl shell (a.k.a.
the REPL to keep running)...
Show quoted text>> I'm sorry I don't know more about why the check
>> for $^S fails in this case. I do know that $^S is
>> undef when you call exit in my case. If you
>> checked for defined() first and then hand off to
>> exit, I think that would work around the crash
>> in the REPL for me.
>
> According to perlvar/EXCEPTIONS_BEING_CAUGHT, "undef" means: error
> during compilation of the code.
>
> I think defined($^S) will not work, because we need to stop the
> program on compilation errors as well. I will check this...
> currently on holidays... so will take some time.
Again, the approach appears to be kill perl if you
think something is wrong rather than letting the
user of your modules make that determination. I'm
just pointing out why some users might need a
different implementation and how it might be done.
Unfortunately, I'm not enough of a perl5-porter to
understand or explain why $^S could be undef when it
*is* being run in an eval structure somewhere. The
current approach makes Log::Report pretty much
unusable for a my application(s) since in general I
try to localize the exception handling as much as
possible rather than having to wrap every line with
try {} catch {}. It needs to be documented at
the least.
I appreciate the dialog. Have a good holiday.
--Chris