digitalmars.D.learn - Can I do an or in a version block?
- Tyler Jameson Little (15/15) Mar 07 2012 I would like to do something like this:
- James Miller (9/24) Mar 07 2012 way
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (33/58) Mar 07 2012 I had played with this in the past. The assignment to version has an
- Steven Schveighoffer (14/39) Mar 08 2012 Noting that there actually isn't an elseif keyword for if either, of
- Andrej Mitrovic (18/18) Mar 08 2012 I find it interesting that having this feature would somehow "enable"
- Jonathan M Davis (22/40) Mar 07 2012 You can do
- Tyler Jameson Little (16/29) Mar 07 2012 Yeah, that was just an example. Perhaps a better example would be
- Tyler Jameson Little (16/29) Mar 07 2012 Yeah, that was just an example. Perhaps a better example would be
- Regan Heath (21/44) Mar 08 2012 IIRC the argument was that we should define version identifiers for
- Jacob Carlborg (5/20) Mar 08 2012 A workaround is to use static if constants, here's a start:
- Ary Manzana (5/20) Mar 08 2012 I don't think it would be hard to implement boolean logic inside version...
- H. S. Teoh (10/13) Mar 08 2012 It's not hard at all.
- Ary Manzana (4/14) Mar 08 2012 What kind of abuses? I don't understand that logic in a language that
- H. S. Teoh (5/25) Mar 08 2012 Ask Walter. It was his opinion.
- Timon Gehr (5/25) Mar 09 2012 Just have a look at reasonably portable C libraries that use the C
- Andrej Mitrovic (5/5) Mar 09 2012 I have a felling people will end up abusing string mixins to generate
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (15/19) Mar 13 2012 D unittest blocks are for code correctness (as opposed to other meanings...
- Ary Manzana (3/22) Mar 13 2012 How can you re-run just a failing test? (without having to run all the
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (14/45) Mar 13 2012 I know that there are test suites too and Unittest++, the framework that...
- Andrej Mitrovic (3/5) Mar 13 2012 Well luckily unittests don't run when you compile a .d file but when
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (9/14) Mar 13 2012 Good point. :)
- H. S. Teoh (35/42) Mar 13 2012 [...]
- Jonathan M Davis (16/18) Mar 13 2012 You can't, not without essentially creating your own unit testing framew...
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?
Mar 07 2012
On 8 March 2012 18:38, Tyler Jameson Little <beatgammit gmail.com> wrote:I would like to do something like this: version (linux || BSD) { =C2=A0 =C2=A0// do something... } else { =C2=A0 =C2=A0version (Windows) { =C2=A0 =C2=A0 =C2=A0 =C2=A0// do something else =C2=A0 =C2=A0} else { =C2=A0 =C2=A0 =C2=A0 =C2=A0// do something else =C2=A0 =C2=A0 =C2=A0 =C2=A0assert(false, "Unsupported operating system"); =C2=A0 =C2=A0} } The only way I've been able to do this, is by splitting up the two versio=nsand repeat code. Is there a better way to do this? A static if can do this, so is there a =waythat 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
Mar 07 2012
On 03/07/2012 10:07 PM, James Miller wrote:On 8 March 2012 18:38, Tyler Jameson Little<beatgammit gmail.com> wrote: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!"); } } AliI 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
Mar 07 2012
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: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) {} -SteveI 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.
Mar 08 2012
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.
Mar 08 2012
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
Mar 07 2012
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!
Mar 07 2012
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!
Mar 07 2012
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/
Mar 08 2012
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
Mar 08 2012
On 3/8/12 2:38 AM, 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?I don't think it would be hard to implement boolean logic inside version. Would it make sense if I make a pull request for it? (because every now and then somebody stumbles upon this issue, and it looks like it could be implemented really easily)
Mar 08 2012
On Thu, Mar 08, 2012 at 05:56:09PM -0300, Ary Manzana wrote: [...]I don't think it would be hard to implement boolean logic inside version.It's not hard at all.Would it make sense if I make a pull request for it?Walter would reject it. He has stated clearly in the past that he intended version to be simple and minimal, and that adding anything onto it will only result in abuses. T -- Why ask rhetorical questions? -- JC
Mar 08 2012
On 3/8/12 6:11 PM, H. S. Teoh wrote:On Thu, Mar 08, 2012 at 05:56:09PM -0300, Ary Manzana wrote: [...]What kind of abuses? I don't understand that logic in a language that allows you to use pointers, alloc memory however you want, and get segfaults for null memory access.I don't think it would be hard to implement boolean logic inside version.It's not hard at all.Would it make sense if I make a pull request for it?Walter would reject it. He has stated clearly in the past that he intended version to be simple and minimal, and that adding anything onto it will only result in abuses.
Mar 08 2012
On Thu, Mar 08, 2012 at 10:25:53PM -0300, Ary Manzana wrote:On 3/8/12 6:11 PM, H. S. Teoh wrote:Ask Walter. It was his opinion. T -- People walk. Computers run.On Thu, Mar 08, 2012 at 05:56:09PM -0300, Ary Manzana wrote: [...]What kind of abuses? I don't understand that logic in a language that allows you to use pointers, alloc memory however you want, and get segfaults for null memory access.I don't think it would be hard to implement boolean logic inside version.It's not hard at all.Would it make sense if I make a pull request for it?Walter would reject it. He has stated clearly in the past that he intended version to be simple and minimal, and that adding anything onto it will only result in abuses.
Mar 08 2012
On 03/09/2012 02:25 AM, Ary Manzana wrote:On 3/8/12 6:11 PM, H. S. Teoh wrote:Just have a look at reasonably portable C libraries that use the C preprocessor for versioning. IIRC Walter pointed to the Hans-Boehm GC the last time this issue was brought up.On Thu, Mar 08, 2012 at 05:56:09PM -0300, Ary Manzana wrote: [...]What kind of abuses?I don't think it would be hard to implement boolean logic inside version.It's not hard at all.Would it make sense if I make a pull request for it?Walter would reject it. He has stated clearly in the past that he intended version to be simple and minimal, and that adding anything onto it will only result in abuses.I don't understand that logic in a language that allows you to use pointers, alloc memory however you want, and get segfaults for null memory access.Sorry, but this does not make any sense.
Mar 09 2012
I have a felling people will end up abusing string mixins to generate version statements, and this will be the exact opposite effect Walter wanted. The same story goes for unittests which can't be independently ran to get a list of all failing unittests, and so people are coming up with their own custom unittest framework (e.g. the Orange library).
Mar 09 2012
On 03/09/2012 06:20 AM, Andrej Mitrovic wrote:The same story goes for unittests which can't be independently ran to get a list of all failing unittestsD unittest blocks are for code correctness (as opposed to other meanings of the unfortunately overused term "unit testing" e.g. the functional testing of the end product). From that point of view, there should not be even a single test failing., and so people are coming up with their own custom unittest framework (e.g. the Orange library).Yes, some unit test features are missing. From my day-to-day use I would like to have the following: - Ensure that a specific exception is thrown - Test fixtures That obviously reflects my use of unit tests but I really don't care how many tests are failing. The reason is, I start with zero failures and I finish with zero failures. Any code that breaks an existing test is either buggy or exposes an issue with the test, which must be dealt with right then. Ali
Mar 13 2012
On 3/13/12 2:21 PM, Ali Çehreli wrote:On 03/09/2012 06:20 AM, Andrej Mitrovic wrote: > The same story goes for unittests which can't be independently > ran to get a list of all failing unittests D unittest blocks are for code correctness (as opposed to other meanings of the unfortunately overused term "unit testing" e.g. the functional testing of the end product). From that point of view, there should not be even a single test failing. >, and so people are coming > up with their own custom unittest framework (e.g. the Orange library). Yes, some unit test features are missing. From my day-to-day use I would like to have the following: - Ensure that a specific exception is thrown - Test fixtures That obviously reflects my use of unit tests but I really don't care how many tests are failing. The reason is, I start with zero failures and I finish with zero failures. Any code that breaks an existing test is either buggy or exposes an issue with the test, which must be dealt with right then. AliHow can you re-run just a failing test? (without having to run all the previous tests that will succeed?)
Mar 13 2012
On 03/13/2012 11:04 AM, Ary Manzana wrote:On 3/13/12 2:21 PM, Ali Çehreli wrote:I know that there are test suites too and Unittest++, the framework that we use, supports them but we don't use suites. There has never been a need to run a subset of the tests for us. The tests almost by definition must run very fast anyway. We don't even notice that they get run automatically as a part of the build process. We are getting a little off topic here but I've been following the recent unit test thread about writing to files. Unit tests should not have external interactions like that either. For example, no test should connect to an actual server to do some interaction. Developers wouldn't want that to happen every time a .d file is compiled. :) (Solutions like mocks, fakes, stubs, etc. do exist. And yes, I know that they are sometimes non-trivial.) AliOn 03/09/2012 06:20 AM, Andrej Mitrovic wrote:How can you re-run just a failing test? (without having to run all the previous tests that will succeed?)The same story goes for unittests which can't be independently ran to get a list of all failing unittestsD unittest blocks are for code correctness (as opposed to other meanings of the unfortunately overused term "unit testing" e.g. the functional testing of the end product). From that point of view, there should not be even a single test failing., and so people are coming up with their own custom unittest framework (e.g. the Orange library).Yes, some unit test features are missing. From my day-to-day use I would like to have the following: - Ensure that a specific exception is thrown - Test fixtures That obviously reflects my use of unit tests but I really don't care how many tests are failing. The reason is, I start with zero failures and I finish with zero failures. Any code that breaks an existing test is either buggy or exposes an issue with the test, which must be dealt with right then. Ali
Mar 13 2012
On 3/13/12, Ali =C7ehreli <acehreli yahoo.com> wrote:Developers wouldn't want that to happen every time a .d file is compiled.Well luckily unittests don't run when you compile a .d file but when you run the app! :)
Mar 13 2012
On 03/13/2012 11:49 AM, Andrej Mitrovic wrote:On 3/13/12, Ali Çehreli<acehreli yahoo.com> wrote:Good point. :) Our C++ unit tests are a part of a test binary that has a make file dependency on the library that the .cc files contribute to. A changed .cc causes its .o to be built, the .o causes its .a to be built, the .a causes its unit test application to be built, and finally the unit test application is executed as a part of the library's post build step. AliDevelopers wouldn't want that to happen every time a .d file is compiled.Well luckily unittests don't run when you compile a .d file but when you run the app! :)
Mar 13 2012
On Tue, Mar 13, 2012 at 11:28:24AM -0700, Ali Çehreli wrote: [...]We are getting a little off topic here but I've been following the recent unit test thread about writing to files. Unit tests should not have external interactions like that either. For example, no test should connect to an actual server to do some interaction. Developers wouldn't want that to happen every time a .d file is compiled. :) (Solutions like mocks, fakes, stubs, etc. do exist. And yes, I know that they are sometimes non-trivial.)[...] It's not about whether unittests should write to files, but about testing a part of the code that operates on files. So you create some test data in the unittest and put it in the file, then pass the file to the function being tested. Ideally, this should be done in some kind of tmpfs, which is only accessible to the program, and which is discarded by the OS once the testing is finished. You still have the case of non-trivial test data, though. Sometimes there's a large dataset with a known result that you want to use in a unittest, to ensure that your latest changes didn't break a known non-trivial working case. I suppose you could argue that these kinds of tests belong in an external test framework, but that's the kind of thing that discourages people from actually writing test cases in the first place. I know I'll be too lazy to do this if it wasn't as simple as adding a unittest block to my code. It's just too much trouble to implement an external framework, write the test case in a separate file, update the build system to include it in the test suite, only to have to scrap a lot of this effort later when you suddenly realize that there's a better algorithm you can use which invalidates most of the original test case. Whereas if this was just an embedded unittest block, you can delete or comment out the block, replace it with a new test relevant to the new code, and keep going. Seems like a small difference, but having to edit 2-3 different files just to update a test case as opposed to continuing to work with the same source file you've been working on can make the difference between the programmer deciding to put it off till later (which usually means it doesn't get done) vs. doing it immediately without too much interruption (test cases are up-to-date and more thorough). T -- I'm still trying to find a pun for "punishment"...
Mar 13 2012
On Tuesday, March 13, 2012 15:04:09 Ary Manzana wrote:How can you re-run just a failing test? (without having to run all the previous tests that will succeed?)You can't, not without essentially creating your own unit testing framework. D's unit testing framework is quite simple. If you compile with -unittest, then the unittest blocks are all run before main is run. If any unittest block in a module fails, then no further unittest blocks in that module are run (though unittest blocks in other modules are run). If any unittest block failed, then main is never run, otherwise the program continues normally. There is no way to rerun specific unit tests or have any control whatsoever which unit tests run unless you create separate programs which only compile in specific modules so that only the unit tests in those modules are run. And even then, you have no control over _which_ tests in a unittest block run unless you play with version statements or whatnot. D's unit testing framework works quite well as long as you're willing to always run all of the tests. If you want more control than that, you have to play games if not outright create your own unit testing framework. - Jonathan M Davis
Mar 13 2012