Jump to page: 1 2
Thread overview
Try/Catch with version condition
Apr 09, 2019
foo
Apr 09, 2019
Julian
Apr 09, 2019
Bastiaan Veelo
Apr 09, 2019
Adam D. Ruppe
Apr 09, 2019
aliak
Apr 09, 2019
Jacob Carlborg
Apr 09, 2019
Walter Bright
Apr 09, 2019
Adam D. Ruppe
Apr 10, 2019
Walter Bright
Apr 09, 2019
Sebastiaan Koppe
Apr 09, 2019
Walter Bright
April 09, 2019
How would I get this to work:

---
version(foo) {
    try {
}
throw new Exception("This should only be fatal when the version is not 'foo'.");
version(foo) {
    } catch (Exception e) {
        import std.stdio;
        writeln(e);
    }
}
---

The only way I could think of to get this to work would be:
---
version(foo) {
    try {
        throw new Exception("This should only be fatal when the version is not 'foo'.");
    } catch (Exception e) {
        import std.stdio;
        writeln(e);
    }
} else {
    throw new Exception("This should only be fatal when the version is not 'foo'.");
}
---

But then that requires too much code duplication.
What would be the best way to do this?
April 09, 2019
On Tuesday, 9 April 2019 at 14:43:54 UTC, foo wrote:
> How would I get this to work:
>
> ---
> version(foo) {
>     try {
> }
> throw new Exception("This should only be fatal when the version is not 'foo'.");
> version(foo) {
>     } catch (Exception e) {
>         import std.stdio;
>         writeln(e);
>     }
> }
> ---
>
> The only way I could think of to get this to work would be:
> ---
> version(foo) {
>     try {
>         throw new Exception("This should only be fatal when the version is not 'foo'.");
>     } catch (Exception e) {
>         import std.stdio;
>         writeln(e);
>     }
> } else {
>     throw new Exception("This should only be fatal when the version is not 'foo'.");
> }
> ---
>
> But then that requires too much code duplication.
> What would be the best way to do this?

Something like this maybe?

  import std.stdio;

  void main() {
      try {
          throw new Exception("fatal for non-foo versions");
      } catch (Exception e) {
          version(foo) {
              writeln(e);
          } else {
              throw(e);
          }
      }
      writeln("continuing, probably in version foo");
  }

As used:

  # dmd -version=foo -run version.d
  object.Exception@version.d(6): fatal for non-foo versions
  ----------------
  ??:? _Dmain [0x9de15af]
  continuing, probably in version foo
  # echo $?
  0

vs.

  # dmd -run version.d
  object.Exception@version.d(6): fatal for non-foo versions
  ----------------
  ??:? _Dmain [0xc4fb9a3]
  # echo $?
  1
April 09, 2019
On Tuesday, 9 April 2019 at 14:43:54 UTC, foo wrote:
> But then that requires too much code duplication.
> What would be the best way to do this?

I'd simply put the try {} body into a helper function, then make the versions just call that function.


void helper() {
   throw new Exception("");
}

version(foo) {
  try helper();
  catch(Exception) {}
} else {
  helper();
}


Remember that with D's nested functions, you can define helper functions just about anywhere and containing the same stuff you'd use directly.
April 09, 2019
On Tuesday, 9 April 2019 at 14:56:03 UTC, Julian wrote:
> Something like this maybe?
>
>   import std.stdio;
>
>   void main() {
>       try {
>           throw new Exception("fatal for non-foo versions");
>       } catch (Exception e) {
>           version(foo) {
>               writeln(e);
>           } else {
>               throw(e);
>           }
>       }
>       writeln("continuing, probably in version foo");
>   }

Beware though that exception handling is not typically performant. From the spec[1]:

> - Errors are not part of the normal flow of a program. Errors are exceptional, unusual, and unexpected.
> - Because errors are unusual, execution of error handling code is not performance critical.

[1] https://dlang.org/spec/errors.html#the_d_error_handling_solution
April 09, 2019
On Tuesday, 9 April 2019 at 15:03:03 UTC, Adam D. Ruppe wrote:
> On Tuesday, 9 April 2019 at 14:43:54 UTC, foo wrote:
>> But then that requires too much code duplication.
>> What would be the best way to do this?
>
> I'd simply put the try {} body into a helper function, then make the versions just call that function.
>
>
> void helper() {
>    throw new Exception("");
> }
>
> version(foo) {
>   try helper();
>   catch(Exception) {}
> } else {
>   helper();
> }
>
>
> Remember that with D's nested functions, you can define helper functions just about anywhere and containing the same stuff you'd use directly.

Aye, I'd do the same. And if you want to generalize it then maybe something like:

void call(alias func)() {
    version (foo) {
        try {
            func();
        } catch (Exception e) {
            writeln(e);
        }
    } else {
        func();
    }
}

void main() {
    call!(() { throw new Exception("Boo"); } );
}

On a side note, this doesn't work: "call!(() => throw new Exception("Boo"))". Is there any reason throw *has* to be a statement and not an expression?

April 09, 2019
On Tuesday, 9 April 2019 at 14:43:54 UTC, foo wrote:
> But then that requires too much code duplication.
> What would be the best way to do this?

I like this approach:

---

import std.stdio;

void tryIt(T)(lazy T t) {
    version (foo)
	try {
    	    t();
	} catch (Exception e) {
	    writeln(e);
	}
    else
        t();
}

void whatever() {
    throw new Exception("Hello");
}

void main() {
    whatever.tryIt();
}

---
April 09, 2019
On 2019-04-09 19:07, aliak wrote:

> Aye, I'd do the same. And if you want to generalize it then maybe something like:
> 
> void call(alias func)() {
>      version (foo) {
>          try {
>              func();
>          } catch (Exception e) {
>              writeln(e);
>          }
>      } else {
>          func();
>      }
> }
> 
> void main() {
>      call!(() { throw new Exception("Boo"); } );
> }
> 
> On a side note, this doesn't work: "call!(() => throw new Exception("Boo"))". Is there any reason throw *has* to be a statement and not an expression?

Here's an alternative, although "throw" is duplicated:

void call(lazy Exception func) {
    version (foo) {
        try {
            throw func();
        } catch (Exception e) {
            writeln(e);
        }
    } else {
        throw func();
    }
}
void main()
{
    call(new Exception("Boo"));
}


-- 
/Jacob Carlborg
April 09, 2019
On 4/9/2019 7:43 AM, foo wrote:
> How would I get this to work:

Nested functions:

 void bar() {
     throw new Exception("This should only be fatal when the version is not 'foo'.");
 }

 version (foo) {
    try { bar(); }
    catch (Exception e) {
        import std.stdio;
        writeln(e);
    }
 }
 else
    bar();
April 09, 2019
On 4/9/2019 8:03 AM, Adam D. Ruppe wrote:
> I'd simply put the try {} body into a helper function, then make the versions just call that function.

I shoulda read this before posting the identical solution!
April 09, 2019
On Tuesday, 9 April 2019 at 23:29:31 UTC, Walter Bright wrote:
> I shoulda read this before posting the identical solution!

Hah! Well, the nested functions are one of my favorite day-to-day tool in D, so they deserve double mention :)
« First   ‹ Prev
1 2