Thread overview
DirEntry isDir not working?
Feb 25, 2013
Josh
Feb 25, 2013
monarch_dodra
Feb 25, 2013
Maxim Fomin
Feb 25, 2013
monarch_dodra
Feb 25, 2013
Maxim Fomin
Feb 25, 2013
Jonathan M Davis
Feb 25, 2013
monarch_dodra
Feb 26, 2013
Jonathan M Davis
February 25, 2013
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
February 25, 2013
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?
February 25, 2013
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
February 25, 2013
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.
February 25, 2013
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.
February 25, 2013
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
February 25, 2013
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?
February 26, 2013
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