www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - DirEntry isDir not working?

reply "Josh" <moonburntm gmail.com> writes:
Code:
import std.file;
import std.stdio;

void main()
{
     writeln(DirEntry("F:\\").isDir());
     writeln(DirEntry("F:").isDir());
     writeln(DirEntry("F:\\folder\\").isDir());
     writeln(DirEntry("F:\\folder").isDir());
     writeln("F:\\".isDir());
     writeln("F:".isDir());
     writeln("F:\\folder\\".isDir());
     writeln("F:\\folder".isDir());
     foreach (d; dirEntries("F:\\", SpanMode.shallow))
     {
         write(d.name ~ "\t");
         writeln(d.isDir());
     }
     foreach (d; dirEntries("F:", SpanMode.shallow))
     {
         write(d.name ~ "\t");
         writeln(d.isDir());
     }
}

Output:
false
false
false
false
true
true
true
true
F:\folder       true
F:\folder       true

Is anybody able to explain why a DirEntry can't seem to detect 
whether a directory is in fact a directory, whereas plain isDir 
and even a DirEntry inside dirEntries can?

Thanks,

Josh
Feb 25 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 25 February 2013 at 08:20:31 UTC, Josh wrote:
 [SNIP]

 Josh
Seems like a massive bug in "DirEntry": It doesn't have a constructor, meaning anybody using "DirEntry" will actually get DirEntry.init. The workaround is to use the function "dirEntry", which returns an initialized DirEntry. This is pretty ridiculous, and I'm baffled no one has seen this yet. May I kindly ask you create a bug entry for this?
Feb 25 2013
next sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Monday, 25 February 2013 at 12:34:05 UTC, monarch_dodra wrote:
 On Monday, 25 February 2013 at 08:20:31 UTC, Josh wrote:
 [SNIP]

 Josh
Seems like a massive bug in "DirEntry": It doesn't have a constructor, meaning anybody using "DirEntry" will actually get DirEntry.init. The workaround is to use the function "dirEntry", which returns an initialized DirEntry.
but see http://d.puremagic.com/issues/show_bug.cgi?id=8563
Feb 25 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 25 February 2013 at 13:45:31 UTC, Maxim Fomin wrote:
 On Monday, 25 February 2013 at 12:34:05 UTC, monarch_dodra 
 wrote:
 On Monday, 25 February 2013 at 08:20:31 UTC, Josh wrote:
 [SNIP]

 Josh
Seems like a massive bug in "DirEntry": It doesn't have a constructor, meaning anybody using "DirEntry" will actually get DirEntry.init. The workaround is to use the function "dirEntry", which returns an initialized DirEntry.
but see http://d.puremagic.com/issues/show_bug.cgi?id=8563
I don't think those have anything to do with each other. 8563 is a dmd bug, which happens to manifest in DirEntry. What the OP is experiencing is just a Phobos bug. Also, 8563 is about the "dirEntr*ies*" range. OP is using a "dirEntr*y*" object. So I think we have two different things to fix here.
Feb 25 2013
parent "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Monday, 25 February 2013 at 14:07:10 UTC, monarch_dodra wrote:
 On Monday, 25 February 2013 at 13:45:31 UTC, Maxim Fomin wrote:
 On Monday, 25 February 2013 at 12:34:05 UTC, monarch_dodra 
 wrote:
 On Monday, 25 February 2013 at 08:20:31 UTC, Josh wrote:
 [SNIP]

 Josh
Seems like a massive bug in "DirEntry": It doesn't have a constructor, meaning anybody using "DirEntry" will actually get DirEntry.init. The workaround is to use the function "dirEntry", which returns an initialized DirEntry.
but see http://d.puremagic.com/issues/show_bug.cgi?id=8563
I don't think those have anything to do with each other. 8563 is a dmd bug, which happens to manifest in DirEntry. What the OP is experiencing is just a Phobos bug. Also, 8563 is about the "dirEntr*ies*" range. OP is using a "dirEntr*y*" object. So I think we have two different things to fix here.
That's clear, I just warn about neighbor bug which can be hit while working with directory entries.
Feb 25 2013
prev sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Monday, February 25, 2013 13:34:04 monarch_dodra wrote:
 On Monday, 25 February 2013 at 08:20:31 UTC, Josh wrote:
 [SNIP]
 
 Josh
Seems like a massive bug in "DirEntry": It doesn't have a constructor, meaning anybody using "DirEntry" will actually get DirEntry.init. The workaround is to use the function "dirEntry", which returns an initialized DirEntry. This is pretty ridiculous, and I'm baffled no one has seen this yet. May I kindly ask you create a bug entry for this?
What I find most odd is that DirEntry("foo") even compiles. It's not giving you DirEntry.init. It's giving you a DirEntry with its first field initialized (which happens to be its name, but that could theoretically change, since that's an implementation detail) but with every other field being its init value. Basically struct S { int i; string s; } auto s = S(5); compiles. I would have thought that the compiler would require that you provide every value if you were using an implicit constructor like that, but apparently not. I don't know if that's a bug or not, though the fact that the fields in DirEntry are private and an implicit constructor still works seems distinctly off to me. Regardless, as its currently implemented, clearly DirEntry was not meant be directly constructed (and it definitely was not meant to be directly constructed in its original form), so the fact that you can is a bug. It didn't even used to be that you could construct a single DirEntry except via dirEntries until I added that capability a while back, but I'm not quite sure why it doesn't use a constructor other than the fact that dirEntries doesn't, and all of the DirEntry code was thoroughly refactored a while back - mostly by me, but I don't remember much of the details of what changed anymore. Part of the problem probably resolves around the fact that it uses _init to initialize itself (which it's always done IIRC). That might be able to be changed to a constructor though. dirEntry matches dirEntries nicely, but I'm not sure that there's a technical reason at this point why DirEntry couldn't have a public constructor taking a string for the path. - Jonathan M Davis
Feb 25 2013
parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
On Monday, 25 February 2013 at 18:23:52 UTC, Jonathan M Davis 
wrote:
 What I find most odd is that DirEntry("foo") even compiles. 
 It's not giving you
 DirEntry.init. It's giving you a DirEntry with its first field 
 initialized
 (which happens to be its name, but that could theoretically 
 change, since
 that's an implementation detail) but with every other field 
 being its init
 value. Basically

 struct S
 {
  int i;
  string s;
 }

 auto s = S(5);

 compiles. I would have thought that the compiler would require 
 that you
 provide every value if you were using an implicit constructor 
 like that, but
 apparently not.

 [SNIP]

 - Jonathan M Davis
No, that's just partial agglomerate construction, and has always worked that way. I think it works that way in C++ too, but I'm not sure (I seldom use POD in C++). What I *am* surprised by though is that it also works with private fields. I'd have expected an "_name is private" compile error. I should create a bug entry, but I kind of expect walter to reply "works as intended"... Since you are the one that refactored, what was the point of those _init functions? Wouldn't they have better worked as private constructors?
Feb 25 2013
parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Monday, February 25, 2013 21:29:28 monarch_dodra wrote:
 Since you are the one that refactored, what was the point of
 those _init functions? Wouldn't they have better worked as
 private constructors?
It's the way that it's always been, but I don't currently remember the details of why I made which changes I made and not others. I suspect that it was done that way, because the code that used the explicitly created them before it initialized them, and I guess that whoever wrote it originally didn't like the idea of doing something like de = DirEntry(args); but I don't know. It's on old module (probably from D1 originally) and has a fair bit of work done on it, but that doesn't mean that no quirks have remained. And DirEntry is somewhat of an odd beast in that it was originally intended to be used only for dirEntries and was more of an abstraction on dirent (like you get with the C readdir). It's changed quite a bit since then. Some of that was me, and some of it wasn't. It's quite possible that some more refactoring is in order, and certainly, the fact that DirEntry("foo") compiles but doesn't work is a problem. Either it shouldn't compile, or it should work. - Jonathan M Davis
Feb 25 2013