Re: Get_Line problem (GNAT bug?)
- From: "Dmitry A. Kazakov" <mailbox@xxxxxxxxxxxxxxxxx>
- Date: Thu, 7 Dec 2006 17:29:27 +0100
On Thu, 07 Dec 2006 15:51:50 +0100, Maciej Sobczak wrote:
Dmitry A. Kazakov wrote:
When End_Of_File meets a CR (Ctrl-M) it cannot know if this CR manifestsI understand. But then I consider the specs to be broken, see below. :-)
the end of the current line or both the line end and the file end.
No. It is the concept, which is broken. And that wasn't Ada, who broke it,
but crippled operating systems like Windows and Unix. In a proper OS the
line terminator is not a character.
That's a brave concept. ;-)
Why do you assign the special meaning to the line terminator?
Because a line can contain any character. Purely mathematically referential
recursion is known to be flawed beyond repair. "All Cretans are liars."
Is it
*that* special in, for example, your previous post? Why not assign the
special meaning to word or sentence terminator? Or anything else for
that matter. Isn't it domain-specific? Do you want support from "proper
OS" for all this stuff?
Yes. A properly designed OS would have a container object to represent
formatted things.
1. Never ever use End_Of_File with text files;This is broken. For me, End_Of_File is a concept that is completely
orthogonal to what the file contains and how it is interpreted.
Right, so see above. You need a file system which has EOF state
determinable without look ahead.
No. I might be using pipes or fifos or sockets or whatever else where
EOF is not really determinable by position. It's not file system issue.
But OS doesn't need pipes, sockets as well as files. It needs objects with
clearly defined behavior. If the behavior is defined to support iteration
and string items, that's called a container of strings.
[Though I don't defend End_Of_File. I would simply remove it from Text_IO.]
But then it would be somewhere else. There would be an opportunity to
specify it correctly, without messing with interpretation of the file
structure.
Yes, it should be a container.
2. If you yet use End_Of_File then do it for *each* character of the file;I don't see how it might solve this problem - End_Of_File would block
after first <CR> anyway.
Yes, but then at least you would know what's going on. End_Of_File happened
to be lower level (in OSI hierarchy terms) than Get_Line.
This is exactly what I would expect. End_Of_File should not mess with
file structure.
But the package is called Text_IO. Texts have a structure. So the problem.
My answer is no. Exception is not an error. It indicates an exceptional
state. Note that an exceptional state is a *valid* state. While an error
(bug) has no corresponding program state at all.
It's not about bugs. I have presented an example of truncated XML file -
there's no bug in a program that happened to be given a broken file to
digest. It's an error in a sense that the program cannot read the data
that it genuinely expects. Still, the program should handle this case
reasonably, so we have valid state.
It is an error in a file, it is not an error in the program. Consider a
defect HDD. Were an exception appropriate here?
Now, if the program specs says: "read the lines from input until EOF",
then this for me immediately translates into a loop with some exit
condition. A while loop, probably, or something in this area. "Read
until" - you have a regular end-of-sequence condition here. Close to
iterators. How do you write iteration routines? Do you use exceptions
for the end-of-sequence condition to break the loop? In what way
iteration over the container is different from reading lines from input?
(Probably the best thing would be to just have "line iterators".)
See below.
Sorry, I'm not convinced that exception might be a correct design choice
for breaking the loop that reads data from well formatted file.
Not only that. I am using exceptions for parsing sources. It fits very
nicely for recursive descent parsing, makes things a lot cleaner and
easier.
This is because you consider it from the C++ stand point.
Which is, of course, evil by definition. ;-)
In Ada exceptions
are efficient.
So how do you write iteration routines?
If you mean the case when the number of iterations is statically
indeterminable, then yes, using exceptions. Especially when iteration is
mixed with recursion.
They are highly recommended for use in place of return
codes.
Good point. There is no return code here. Everything is managed at the
same level. The red-light here is that with exceptions I would need to
use empty "where" clause. Empty clause at the same level?
Umm, I didn't understand it, but the skeleton code looks like:
Protocol_Error : exception;
begin
loop
Line := Get_Line (Source);
-- do something. This may raise an exception as well
end loop;
exception
when End_Error =>
-- done due to file end
when Data_Error =>
-- due to I/O error
when Protocol_Error =>
-- due to protocol error
...
end;
Looks like goto in disguise.
Any execution flow control is. So exceptions are as well.
End_Of_File in your program serves the
purpose of return code.
Nope. It's the end-of-sequence condition. Just like with iterators.
But Get_Line already has a result, which is a string. String is not a
condition.
What is even worse, from the software design
perspective, is that one operation "give me next line" is split into two,
so that the side effect of one determines the outcome of another and
reverse.
Same with iterators.
That's a different idiom. Iterators assume an indexed container. You could
use iterators for dealing with a container of strings. But a stream isn't
one. It is again about mixing abstraction levels. You can convert a
character stream into a sequence of strings, but the stream itself is a
container of characters, not lines. While a text file is a third thing.
And what for? To defend a myth, that each
loop should have only one exit?
If the specs says "read until end", then this means single exit
condition to me.
No. This is mixing problem and solution spaces. What if I had a concurrent
program, which would map the file into virtual memory. Then I could split
that memory into 10 pieces and let 10 tasks "read it until end."
Your code didn't managed that either!
Why?
Because it contained a hidden goto: "exit when!" (:-))
Neither manages it inputs longer than 99 characters.
Good point. How should I solve this?
By making the main loop dealing with lines instead of reads. This is
another reason, why it is not a clean iteration idiom.
Further, even in C you wouldn't use it either.
You're right, I wouldn't. Why would I use C if C++ gets it right? ;-)
string line;
while (getline(cin, line))
{
// play with line here
}
That's OK to me. However, it is not that clean. line outlives the loop. But
it is not equivalent to your Ada code, because you chose fixed-length
strings. An Ada equivalent of your C++ example would use Unbounded_String.
Then what happens upon read error, reading the system paging file?
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
.
- References:
- Get_Line problem (GNAT bug?)
- From: Maciej Sobczak
- Re: Get_Line problem (GNAT bug?)
- From: Dmitry A. Kazakov
- Re: Get_Line problem (GNAT bug?)
- From: Maciej Sobczak
- Re: Get_Line problem (GNAT bug?)
- From: Dmitry A. Kazakov
- Re: Get_Line problem (GNAT bug?)
- From: Maciej Sobczak
- Get_Line problem (GNAT bug?)
- Prev by Date: Re: Get_Line problem (GNAT bug?)
- Next by Date: Re: Get_Line problem (GNAT bug?)
- Previous by thread: Re: Get_Line problem (GNAT bug?)
- Next by thread: Re: Get_Line problem (GNAT bug?)
- Index(es):
Relevant Pages
|
Loading