www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - scope() and FileConduit (D1 and Tango)

reply "Nick Sabalausky" <a a.a> writes:
I'd like some clarification on the way scope() works, and also Tango's 
FileConduit. In the following function:

void load(char[] infilename)
{
    auto file = new FileConduit(infilename);
    scope(exit) file.close();

    // Load data
}

What happens if infilename doesn't exist? Does FileConduit's constructor 
throw an exception? If so, file.close() isn't called, is it? 
Oct 03 2008
next sibling parent "Bill Baxter" <wbaxter gmail.com> writes:
You might be interested in the siblings of scope(exit):
scope(success) and scope(failure).

In particular, scope(success) file.close(); is probably what you're after here.

--bb

On Sat, Oct 4, 2008 at 5:57 AM, Nick Sabalausky <a a.a> wrote:
 I'd like some clarification on the way scope() works, and also Tango's
 FileConduit. In the following function:

 void load(char[] infilename)
 {
    auto file = new FileConduit(infilename);
    scope(exit) file.close();

    // Load data
 }

 What happens if infilename doesn't exist? Does FileConduit's constructor
 throw an exception? If so, file.close() isn't called, is it?

Oct 03 2008
prev sibling next sibling parent reply "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Fri, Oct 3, 2008 at 4:57 PM, Nick Sabalausky <a a.a> wrote:
 I'd like some clarification on the way scope() works, and also Tango's
 FileConduit. In the following function:

 void load(char[] infilename)
 {
    auto file = new FileConduit(infilename);
    scope(exit) file.close();

    // Load data
 }

 What happens if infilename doesn't exist? Does FileConduit's constructor
 throw an exception? If so, file.close() isn't called, is it?

Yes, the ctor throws an exception. No, file.close is never called. scope statements are only executed if execution reaches them successfully.
Oct 03 2008
parent reply "Nick Sabalausky" <a a.a> writes:
"Jarrett Billingsley" <jarrett.billingsley gmail.com> wrote in message 
news:mailman.4.1223071686.3520.digitalmars-d-learn puremagic.com...
 On Fri, Oct 3, 2008 at 4:57 PM, Nick Sabalausky <a a.a> wrote:
 I'd like some clarification on the way scope() works, and also Tango's
 FileConduit. In the following function:

 void load(char[] infilename)
 {
    auto file = new FileConduit(infilename);
    scope(exit) file.close();

    // Load data
 }

 What happens if infilename doesn't exist? Does FileConduit's constructor
 throw an exception? If so, file.close() isn't called, is it?

Yes, the ctor throws an exception. No, file.close is never called. scope statements are only executed if execution reaches them successfully.

Thanks. A minor followup question (more of a curiosity, really): If .close() is called on a conduit that is already closed, is this silently accepted or is there a "Tried to close a non-open conduit" exception? And is that behavior a defined part of the API, or just sort of "That's what it does right now, but it's not officially guaranteed to do that"? Also, it looks like neither FileConduit nor its base classes have a destructor, which suggests to me I can't use RTTI and replace both lines in the code sample above with "scope file = new FileConduit(infilename);". Any particular reason for this, or is it a possible future enhancement?
Oct 03 2008
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Nick Sabalausky" wrote
 "Jarrett Billingsley" <jarrett.billingsley gmail.com> wrote in message 
 news:mailman.4.1223071686.3520.digitalmars-d-learn puremagic.com...
 On Fri, Oct 3, 2008 at 4:57 PM, Nick Sabalausky <a a.a> wrote:
 I'd like some clarification on the way scope() works, and also Tango's
 FileConduit. In the following function:

 void load(char[] infilename)
 {
    auto file = new FileConduit(infilename);
    scope(exit) file.close();

    // Load data
 }

 What happens if infilename doesn't exist? Does FileConduit's constructor
 throw an exception? If so, file.close() isn't called, is it?

Yes, the ctor throws an exception. No, file.close is never called. scope statements are only executed if execution reaches them successfully.

Thanks. A minor followup question (more of a curiosity, really): If .close() is called on a conduit that is already closed, is this silently accepted or is there a "Tried to close a non-open conduit" exception? And is that behavior a defined part of the API, or just sort of "That's what it does right now, but it's not officially guaranteed to do that"?

If you use FileConduit the way you are saying above, and the ctor throws an exception, then the variable is null, so you would get a null-pointer exception first.
 Also, it looks like neither FileConduit nor its base classes have a 
 destructor, which suggests to me I can't use RTTI and replace both lines 
 in the code sample above with "scope file = new FileConduit(infilename);". 
 Any particular reason for this, or is it a possible future enhancement?

I'll let my previous discussion with Kris speak to that issue: http://www.dsource.org/projects/tango/forums/topic/260 -Steve
Oct 04 2008
prev sibling next sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Fri, Oct 3, 2008 at 6:44 PM, Nick Sabalausky <a a.a> wrote:
 "Jarrett Billingsley" <jarrett.billingsley gmail.com> wrote in message
 news:mailman.4.1223071686.3520.digitalmars-d-learn puremagic.com...
 On Fri, Oct 3, 2008 at 4:57 PM, Nick Sabalausky <a a.a> wrote:
 I'd like some clarification on the way scope() works, and also Tango's
 FileConduit. In the following function:

 void load(char[] infilename)
 {
    auto file = new FileConduit(infilename);
    scope(exit) file.close();

    // Load data
 }

 What happens if infilename doesn't exist? Does FileConduit's constructor
 throw an exception? If so, file.close() isn't called, is it?

Yes, the ctor throws an exception. No, file.close is never called. scope statements are only executed if execution reaches them successfully.

Thanks. A minor followup question (more of a curiosity, really): If .close() is called on a conduit that is already closed, is this silently accepted or is there a "Tried to close a non-open conduit" exception? And is that behavior a defined part of the API, or just sort of "That's what it does right now, but it's not officially guaranteed to do that"?

It's currently harmless. I don't know if it's defined or not.
 Also, it looks like neither FileConduit nor its base classes have a
 destructor, which suggests to me I can't use RTTI and replace both lines in
 the code sample above with "scope file = new FileConduit(infilename);". Any
 particular reason for this, or is it a possible future enhancement?

It's pretty simple to derive it yourself, but it does seem like something that should be there. scope class AutocloseFile : FileConduit { this(char[] name) { super(name); } ~this() { close(); } }
Oct 03 2008
prev sibling next sibling parent "Bill Baxter" <wbaxter gmail.com> writes:
On Sat, Oct 4, 2008 at 7:08 AM, Jarrett Billingsley
<jarrett.billingsley gmail.com> wrote:
 On Fri, Oct 3, 2008 at 4:57 PM, Nick Sabalausky <a a.a> wrote:
 I'd like some clarification on the way scope() works, and also Tango's
 FileConduit. In the following function:

 void load(char[] infilename)
 {
    auto file = new FileConduit(infilename);
    scope(exit) file.close();

    // Load data
 }

 What happens if infilename doesn't exist? Does FileConduit's constructor
 throw an exception? If so, file.close() isn't called, is it?

Yes, the ctor throws an exception. No, file.close is never called. scope statements are only executed if execution reaches them successfully.

Oh, ok I see what the issue is now. I think this will do the right thing: void load(char[] infilename) { FileConduit file; scope(exit) { if (file) file.close(); } file = new FileConduit(infilename); // Load data } You could use "scope(success) file.close();" there instead, but that's going to be wrong if an exception is thrown down in the "//Load data" part. --bb
Oct 03 2008
prev sibling next sibling parent "Jarrett Billingsley" <jarrett.billingsley gmail.com> writes:
On Fri, Oct 3, 2008 at 8:58 PM, Bill Baxter <wbaxter gmail.com> wrote:
 On Sat, Oct 4, 2008 at 7:08 AM, Jarrett Billingsley
 <jarrett.billingsley gmail.com> wrote:
 On Fri, Oct 3, 2008 at 4:57 PM, Nick Sabalausky <a a.a> wrote:
 I'd like some clarification on the way scope() works, and also Tango's
 FileConduit. In the following function:

 void load(char[] infilename)
 {
    auto file = new FileConduit(infilename);
    scope(exit) file.close();

    // Load data
 }

 What happens if infilename doesn't exist? Does FileConduit's constructor
 throw an exception? If so, file.close() isn't called, is it?

Yes, the ctor throws an exception. No, file.close is never called. scope statements are only executed if execution reaches them successfully.

Oh, ok I see what the issue is now. I think this will do the right thing: void load(char[] infilename) { FileConduit file; scope(exit) { if (file) file.close(); } file = new FileConduit(infilename); // Load data }

That's pretty much unnecessary, since in this code: auto file = new FileConduit(infilename); scope(exit) file.close(); if FileConduit's constructor fails, there is no file to close, so there's no need to check for that.
Oct 03 2008
prev sibling parent "Bill Baxter" <wbaxter gmail.com> writes:
On Sat, Oct 4, 2008 at 10:11 AM, Jarrett Billingsley
<jarrett.billingsley gmail.com> wrote:
 On Fri, Oct 3, 2008 at 8:58 PM, Bill Baxter <wbaxter gmail.com> wrote:
 On Sat, Oct 4, 2008 at 7:08 AM, Jarrett Billingsley
 <jarrett.billingsley gmail.com> wrote:
 On Fri, Oct 3, 2008 at 4:57 PM, Nick Sabalausky <a a.a> wrote:
 I'd like some clarification on the way scope() works, and also Tango's
 FileConduit. In the following function:

 void load(char[] infilename)
 {
    auto file = new FileConduit(infilename);
    scope(exit) file.close();

    // Load data
 }

 What happens if infilename doesn't exist? Does FileConduit's constructor
 throw an exception? If so, file.close() isn't called, is it?

Yes, the ctor throws an exception. No, file.close is never called. scope statements are only executed if execution reaches them successfully.

Oh, ok I see what the issue is now. I think this will do the right thing: void load(char[] infilename) { FileConduit file; scope(exit) { if (file) file.close(); } file = new FileConduit(infilename); // Load data }

That's pretty much unnecessary, since in this code: auto file = new FileConduit(infilename); scope(exit) file.close(); if FileConduit's constructor fails, there is no file to close, so there's no need to check for that.

Oh yeh. Good point. --bb
Oct 03 2008