View mode: basic / threaded / horizontal-split · Log in · Help
March 08, 2012
Can I do an or in a version block?
I would like to do something like this:

version (linux || BSD) {
    // do something...
} else {
    version (Windows) {
        // do something else
    } else {
        // do something else
        assert(false, "Unsupported operating system");
    }
}

The only way I've been able to do this, is by splitting up the 
two versions and repeat code.

Is there a better way to do this? A static if can do this, so is 
there a way that I can use a static if somehow?
March 08, 2012
Re: Can I do an or in a version block?
On 8 March 2012 18:38, Tyler Jameson Little <beatgammit@gmail.com> wrote:
> I would like to do something like this:
>
> version (linux || BSD) {
>    // do something...
> } else {
>    version (Windows) {
>        // do something else
>    } else {
>        // do something else
>        assert(false, "Unsupported operating system");
>    }
> }
>
> The only way I've been able to do this, is by splitting up the two versions
> and repeat code.
>
> Is there a better way to do this? A static if can do this, so is there a way
> that I can use a static if somehow?

I don't think there is an 'elseif' for versions, probably because you
are normally checking mutually exclusive version descriptions.
Otherwise, its probably a good idea to keep the syntax as is, since it
stops people from abusing the mechanic.

--
James Miller
March 08, 2012
Re: Can I do an or in a version block?
On 03/07/2012 10:07 PM, James Miller wrote:
> On 8 March 2012 18:38, Tyler Jameson Little<beatgammit@gmail.com>  wrote:
>> I would like to do something like this:
>>
>> version (linux || BSD) {
>>     // do something...
>> } else {
>>     version (Windows) {
>>         // do something else
>>     } else {
>>         // do something else
>>         assert(false, "Unsupported operating system");
>>     }
>> }
>>
>> The only way I've been able to do this, is by splitting up the two versions
>> and repeat code.
>>
>> Is there a better way to do this? A static if can do this, so is there a way
>> that I can use a static if somehow?
>
> I don't think there is an 'elseif' for versions, probably because you
> are normally checking mutually exclusive version descriptions.
> Otherwise, its probably a good idea to keep the syntax as is, since it
> stops people from abusing the mechanic.
>
> --
> James Miller

I had played with this in the past. The assignment to version has an 
interesting meaning of "collecting" everything assigned to it:

import std.stdio;

version (linux)
{
    version = linuxOrBSD;
    version = foo;
}

version (BSD)
{
    version = linuxOrBSD;
    version = foo;
}

void main()
{
    version (linuxOrBSD) {
        writeln("linux or BSD");
        // do something...
    } else {
        version (Windows) {
            // do something else
        } else {
            // do something else
            assert(false, "Unsupported operating system");
        }
    }

    // Later on even this works
    version (foo) {
        writeln("even foo!");
    }
}

Ali
March 08, 2012
Re: Can I do an or in a version block?
On Thursday, March 08, 2012 06:38:48 Tyler Jameson Little wrote:
> I would like to do something like this:
> 
> version (linux || BSD) {
>      // do something...
> } else {
>      version (Windows) {
>          // do something else
>      } else {
>          // do something else
>          assert(false, "Unsupported operating system");
>      }
> }
> 
> The only way I've been able to do this, is by splitting up the
> two versions and repeat code.
> 
> Is there a better way to do this? A static if can do this, so is
> there a way that I can use a static if somehow?

You can do

version(x) {}
else version(y) {}
else {}

but there is no logical and or logical or with versions. It's _only_ checking 
whether a particular version exists or not. Walter Bright is completely 
against having anything more complicated with versioning, since he thinks that 
it just engenders bad code and bugs.

Now, you could do

version(x)
   version = xOrY
else version(y)
   version = xOrY

version(xOrY) {}

and then xOrY will exist for the rest of that module. But that's as close as 
you're going to ge to logical and or logical or for versions.

Of course, if the issue is linux || FreeBSD, you might want to just consider 
using Posix. Unless you're doing something that is specific to linux and 
FreeBSD but not Posix in general (which I would expect to be unlikely), Posix 
will do the trick just fine.

- Jonathan M Davis
March 08, 2012
Re: Can I do an or in a version block?
> Now, you could do
>
> version(x)
>     version = xOrY
> else version(y)
>     version = xOrY
>
> version(xOrY) {}

Huh, clever! I like it!! I hope I don't have to do that very 
often, though...

> Of course, if the issue is linux || FreeBSD, you might want to 
> just consider
> using Posix. Unless you're doing something that is specific to 
> linux and
> FreeBSD but not Posix in general (which I would expect to be 
> unlikely), Posix
> will do the trick just fine.

Yeah, that was just an example. Perhaps a better example would be 
comparing versions of something:

version (LIBV1 || LIBV2) {
    // include some dirty hacks for old versions
} else {
    // do some new fancy stuff for new features
}

I was mostly thinking that there are things that linux and BSD 
share that other BSDs may not. I know that Mac OS X has some 
subtle differences in a few things.

Anyway, I think this answers my question. I can get by with using 
your suggestion for those (hopefully) rare cases where I need 
something more specific.

Thanks!
March 08, 2012
Re: Can I do an or in a version block?
> Now, you could do
>
> version(x)
>     version = xOrY
> else version(y)
>     version = xOrY
>
> version(xOrY) {}

Huh, clever! I like it!! I hope I don't have to do that very 
often, though...

> Of course, if the issue is linux || FreeBSD, you might want to 
> just consider
> using Posix. Unless you're doing something that is specific to 
> linux and
> FreeBSD but not Posix in general (which I would expect to be 
> unlikely), Posix
> will do the trick just fine.

Yeah, that was just an example. Perhaps a better example would be 
comparing versions of something:

version (LIBV1 || LIBV2) {
    // include some dirty hacks for old versions
} else {
    // do some new fancy stuff for new features
}

I was mostly thinking that there are things that linux and BSD 
share that other BSDs may not. I know that Mac OS X has some 
subtle differences in a few things.

Anyway, I think this answers my question. I can get by with using 
your suggestion for those (hopefully) rare cases where I need 
something more specific.

Thanks!
March 08, 2012
Re: Can I do an or in a version block?
On 2012-03-08 06:38, Tyler Jameson Little wrote:
> I would like to do something like this:
>
> version (linux || BSD) {
> // do something...
> } else {
> version (Windows) {
> // do something else
> } else {
> // do something else
> assert(false, "Unsupported operating system");
> }
> }
>
> The only way I've been able to do this, is by splitting up the two
> versions and repeat code.
>
> Is there a better way to do this? A static if can do this, so is there a
> way that I can use a static if somehow?

A workaround is to use static if constants, here's a start:

https://github.com/jacob-carlborg/mambo/blob/master/util/Version.d

-- 
/Jacob Carlborg
March 08, 2012
Re: Can I do an or in a version block?
On Thu, 08 Mar 2012 06:12:44 -0000, Jonathan M Davis <jmdavisProg@gmx.com>  
wrote:
> On Thursday, March 08, 2012 06:38:48 Tyler Jameson Little wrote:
>> I would like to do something like this:
>>
>> version (linux || BSD) {
>>      // do something...
>> } else {
>>      version (Windows) {
>>          // do something else
>>      } else {
>>          // do something else
>>          assert(false, "Unsupported operating system");
>>      }
>> }
>>
>> The only way I've been able to do this, is by splitting up the
>> two versions and repeat code.
>>
>> Is there a better way to do this? A static if can do this, so is
>> there a way that I can use a static if somehow?

> <snip>... Walter Bright is completely
> against having anything more complicated with versioning, since he  
> thinks that
> it just engenders bad code and bugs.

IIRC the argument was that we should define version identifiers for  
'features' or 'behaviours' not for platforms, etc.

So, given the 2nd example, instead of:

version (LIBV1 || LIBV2) {
    // include some dirty hacks for old versions
} else {
    // do some new fancy stuff for new features
}

do:

version (LIBV1) version = LIB_OLD
version (LIBV2) version = LIB_OLD

version (LIB_OLD) {
  // dirty hacks
} else {
  // new fancy stuff
}

Regan

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
March 08, 2012
Re: Can I do an or in a version block?
On Thu, 08 Mar 2012 01:07:08 -0500, James Miller <james@aatch.net> wrote:

> On 8 March 2012 18:38, Tyler Jameson Little <beatgammit@gmail.com> wrote:
>> I would like to do something like this:
>>
>> version (linux || BSD) {
>>    // do something...
>> } else {
>>    version (Windows) {
>>        // do something else
>>    } else {
>>        // do something else
>>        assert(false, "Unsupported operating system");
>>    }
>> }
>>
>> The only way I've been able to do this, is by splitting up the two  
>> versions
>> and repeat code.
>>
>> Is there a better way to do this? A static if can do this, so is there  
>> a way
>> that I can use a static if somehow?
>
> I don't think there is an 'elseif' for versions, probably because you
> are normally checking mutually exclusive version descriptions.
> Otherwise, its probably a good idea to keep the syntax as is, since it
> stops people from abusing the mechanic.

Noting that there actually isn't an elseif keyword for if either, of  
course there is the same construct for version:

// if
if(cond1)
{}
else if(cond2)
{}

// version
version(version1)
{}
else version(version2)
{}

-Steve
March 08, 2012
Re: Can I do an or in a version block?
I find it interesting that having this feature would somehow "enable"
abuse, yet we can do so much abuse already with CTFE, templates, and
string mixins. One large pain in the ass is to pass an integral at
compile time. I sometimes wish to use a syntax such as "version(foo ==
5) {}". The only alternative that I know of is to use string imports
via -J switch to initialize an enum. Compare that with the simple
-Dfoo=5 in DMC/GCC/etc. We might not have globals or macros in D, but
at least 'version(foo) = 5' or something similar should work. It's
also strange that version uses its own meaning of the equals operator,
I really dislike that.

Generally it seems version is the poorest-developed feature of D. And
the counterargument for new features is always a Go-like stance ("you
just won't need it"/"people will abuse the feature").

Of course all I can do now is whine and not propose something better.
:) But there have been a few threads about version and its issues. I
think it's only a matter of time before D gets popular enough that we
get these kinds of threads every other day. Maybe then something will
change.
« First   ‹ Prev
1 2 3
Top | Discussion index | About this forum | D home