Nick Sabalausky wrote:
I have to admit, that's a very compelling example. I hadn't thought of
anything like that.
I didn't either, until I got bit by it <g>.
I guess the moral is "DRY is normally great, but be very
careful with it when using it across multiple builds." But I'm still not
sure we should be going that far. For instance:
enum
{
version(Linux || OSX)
{
O_RDONLY = 0,
O_WRONLY = 1,
O_RDWR = 2,
O_CREAT = 0100,
}
version(Linux)
{
O_APPEND = 02000,
}
version(OSX)
{
O_APPEND = 8,
O_SYMLINK = 0x200000,
}
}
That seems reasonable to me.
Yeah, but I guarantee you that there will be some "common to all" ones
and an irresistible temptation to put them in outside any version block.
I also like to have all the enums for one platform in one list, not
broken up by other stuff for other platforms, because then it is easier
to verify against the C headers.
Besides, without expression-level version(), the project's author might just
as likely think "Shoot, this is stupid that D doesn't let me make this
nicely DRY. But I really like DRY, so I guess I'll just resort to an
external C-like pre-processor".
There's something wrong with that option, because although it's always
been on the table (not just for D, but for any language) nobody ever
uses it.
Back in the '80s people would often complain about the limitations of
the C preprocessor, and the answer was always "if you want a real macro
preprocessor, use m4". But I've never heard of anyone ever actually
using m4 to preprocess C. The "just use m4" meme became a joke, like Bob
Villa saying "just use track lighting".