Thread overview
scope file.open
Jan 23, 2007
nobody
Jan 23, 2007
Frits van Bommel
Jan 24, 2007
nobody
Jan 24, 2007
Frits van Bommel
January 23, 2007
Hallo,

how can i saftly open a file with scope.
My  idea is:
import std.stream;
import std.stdio;

void main() {
        File file = new File;

        scope(failure) {
                writefln("Datei kann nicht geoeffnet werden ");
        }
        file.open("testdatei.txt",FileMode.In);

        while(!file.eof()) {
                printf("%.*s\n",file.readLine());

        }
        file.close();
}


But why must scope(failure) before the file.open statement.
I think it's look strange.
Mybe some on have a better idea to open a file with scope.

Sincerily

January 23, 2007
nobody wrote:
> Hallo,
> 
> how can i saftly open a file with scope.
> My  idea is:
> import std.stream;
> import std.stdio;
> 
> void main() {
>         File file = new File;
> 
>         scope(failure) {
>                 writefln("Datei kann nicht geoeffnet werden ");
>         }
>         file.open("testdatei.txt",FileMode.In);
> 
>         while(!file.eof()) {
>                 printf("%.*s\n",file.readLine());
> 
>         }
>         file.close();
> }
> 
> 
> But why must scope(failure) before the file.open statement.
> I think it's look strange.
> Mybe some on have a better idea to open a file with scope.
> 
> Sincerily
> 

Personally I don't think it really looks all that strange, but I'm odd like that.  :)  In this case, if it worries you, you might try a traditional try-catch-finally instead.

# void main () {
#   File file = new File ;
#
#   try {
#     file.open("testdatei.txt",FileMode.In);
#     while(!file.eof()) {
#       printf("%.*s\n",file.readLine());
#     }
#   }
#   catch (Exception x) {
#     writefln("Datei kann nicht geoeffnet werden ");
#     throw x;
#   }
#
#   file.close();
# }

-- Chris Nicholson-Sauls
January 23, 2007
Chris Nicholson-Sauls wrote:
> nobody wrote:
>> Hallo,
>>
>> how can i saftly open a file with scope.
>> My  idea is:
[snip]
>> But why must scope(failure) before the file.open statement.
>> I think it's look strange.
>> Mybe some on have a better idea to open a file with scope.
> 
> Personally I don't think it really looks all that strange, but I'm odd like that.  :)  In this case, if it worries you, you might try a traditional try-catch-finally instead.
> 
> # void main () {
> #   File file = new File ;
> #
> #   try {
> #     file.open("testdatei.txt",FileMode.In);
> #     while(!file.eof()) {
> #       printf("%.*s\n",file.readLine());
> #     }
> #   }
> #   catch (Exception x) {
> #     writefln("Datei kann nicht geoeffnet werden ");
> #     throw x;
> #   }
> #
> #   file.close();
> # }

While you're at it, either
* put 'scope' in front of the 'File file' declaration, or
* move 'file.close()' into a finally{} block at the end of that try-catch, or
* put 'scope(exit) file.close();' right after the declaration of file

All of those will guarantee your file gets closed if an exception gets thrown. I'd personally prefer the first one, but if you're going to use try-catch anyway you might as well tack on a 'finally'.

Of course, it doesn't really matter in this case since it's directly in main(), and the exception will exit it...
January 24, 2007
Chris Nicholson-Sauls Wrote:

> nobody wrote:
> > Hallo,
> > 
> > how can i saftly open a file with scope.
> > My  idea is:
> > import std.stream;
> > import std.stdio;
> > 
> > void main() {
> >         File file = new File;
> > 
> >         scope(failure) {
> >                 writefln("Datei kann nicht geoeffnet werden ");
> >         }
> >         file.open("testdatei.txt",FileMode.In);
> > 
> >         while(!file.eof()) {
> >                 printf("%.*s\n",file.readLine());
> > 
> >         }
> >         file.close();
> > }
> > 
> > 
> > But why must scope(failure) before the file.open statement.
> > I think it's look strange.
> > Mybe some on have a better idea to open a file with scope.
> > 
> > Sincerily
> > 
> 
> Personally I don't think it really looks all that strange, but I'm odd like that.  :)  In this case, if it worries you, you might try a traditional try-catch-finally instead.
> 
> # void main () {
> #   File file = new File ;
> #
> #   try {
> #     file.open("testdatei.txt",FileMode.In);
> #     while(!file.eof()) {
> #       printf("%.*s\n",file.readLine());
> #     }
> #   }
> #   catch (Exception x) {
> #     writefln("Datei kann nicht geoeffnet werden ");
> #     throw x;
> #   }
> #
> #   file.close();
> # }
> 
> -- Chris Nicholson-Sauls

The question is, how scope know it's a failure to open a file, before the file.open statement
is executed.
That is i didn't understand.
For this reason, i will put the scope(failure) after the file.open statement.

Thanks



January 24, 2007
"nobody" <not@possible.de> wrote in message news:ep7395$o92$1@digitaldaemon.com...

> The question is, how scope know it's a failure to open a file, before the
> file.open statement
> is executed.
> That is i didn't understand.

What the scope(failure) statement does is "registers" the following piece of code to be executed whenever the current scope (brace block) is left.  So you can put it anywhere:

scope(failure) writefln("Datei kann nicht geoeffnet werden ");
File file = new File;
file.open("testdatei.txt",FileMode.In);
while(!file.eof()) writefln(file.readLine());
file.close();

Or:

File file = new File;
scope(failure) writefln("Datei kann nicht geoeffnet werden ");
file.open("testdatei.txt",FileMode.In);
while(!file.eof()) writefln(file.readLine());
file.close();

Or even:

File file = new File;
file.open("testdatei.txt",FileMode.In);
while(!file.eof()) writefln(file.readLine());
file.close();
scope(failure) writefln("Datei kann nicht geoeffnet werden ");

It doesn't matter where the scope(failure) appears.  It just means "if an exception passes out of this block, run this code."


January 24, 2007
Jarrett Billingsley wrote:
> "nobody" <not@possible.de> wrote in message news:ep7395$o92$1@digitaldaemon.com...
> 
>> The question is, how scope know it's a failure to open a file, before the file.open statement
>> is executed.
>> That is i didn't understand.
> 
> What the scope(failure) statement does is "registers" the following piece of code to be executed whenever the current scope (brace block) is left.  So you can put it anywhere:

1) It only gets executed when the scope is exited by exception unwinding.
2) It only gets executed when that exception happens *after* the scope statement.

http://www.digitalmars.com/d/statement.html#ScopeGuardStatement

> scope(failure) writefln("Datei kann nicht geoeffnet werden ");
> File file = new File;
> file.open("testdatei.txt",FileMode.In);
> while(!file.eof()) writefln(file.readLine());
> file.close();

That'll work.

> Or:
> 
> File file = new File;
> scope(failure) writefln("Datei kann nicht geoeffnet werden ");
> file.open("testdatei.txt",FileMode.In);
> while(!file.eof()) writefln(file.readLine());
> file.close();

That'll only print if 'new File' is successful (i.e. there's enough memory and the constructor doesn't throw an exception) but an exception gets thrown in the rest of the code.

> Or even:
> 
> File file = new File;
> file.open("testdatei.txt",FileMode.In);
> while(!file.eof()) writefln(file.readLine());
> file.close();
> scope(failure) writefln("Datei kann nicht geoeffnet werden ");

That will *not* work. It's just too late to affect any code.

> It doesn't matter where the scope(failure) appears.  It just means "if an exception passes out of this block, run this code." 

It's "If an exception passes out of this block *after this statement*, run this code", actually.

See for yourself:
-----
urxae@urxae:~/tmp$ cat test.d
import std.stdio;

void main() {
    scope(failure) writefln("will print");
    throw new Exception("will be thrown");
    scope(failure) writefln("won't print");
}
urxae@urxae:~/tmp$ dmd -run test.d
will print
Error: will be thrown
-----