digitalmars.D.learn - How to avoid throwing an exceptions for a built-in function?
- k-five (15/15) May 10 2017 I have a line of code that uses "to" function in std.conv for a
- Nicholas Wilson (4/19) May 10 2017 there has been talk of adding an overload that substitutes a
- Ivan Kazmenko (19/34) May 10 2017 I assume that an empty string is a valid input then.
- k-five (5/24) May 10 2017 ----------------------------------------------------------
- Stanislav Blinov (6/8) May 10 2017 That doesn't sound right. Either you've already handled all the
- k-five (16/25) May 10 2017 ------------------------------------------------------------------
- Stanislav Blinov (18/46) May 10 2017 I don't understand. If you don't want to take care of exceptions,
- Moritz Maxeiner (7/10) May 10 2017 nothrow disallows the function scope to throw exceptions not
- k-five (23/28) May 11 2017 Well I did that, but when the string is a valid type like: "10"
- Mike B Johnson (22/52) May 12 2017 You are not making a lot of sense:
- k-five (20/41) May 13 2017 ----------------------------------------------------------------
- Stanislav Blinov (22/44) May 13 2017 Please don't take it the wrong way. It just seems that Mike was
- Andrei Alexandrescu (3/20) May 10 2017 Use the "parse" family: https://dlang.org/phobos/std_conv.html#parse --
- k-five (37/42) May 11 2017 -----------------------------------
- =?UTF-8?Q?Ali_=c3=87ehreli?= (44/56) May 10 2017 Are you really fine with 'index' being left with its previous value? If
- crimaniak (3/18) May 11 2017 try this:
- k-five (13/16) May 11 2017 Worked. Thanks.
- H. S. Teoh via Digitalmars-d-learn (8/29) May 11 2017 Keep in mind, though, that you should not do this in an inner loop if
- Jordan Wilson (6/35) May 11 2017 This reason is why I sometimes use isNumeric if I have heaps of
- k-five (6/17) May 12 2017 --------------------------------------------------------------
- k-five (8/27) May 12 2017 ----------------------------------------------------------------
- Jonathan M Davis via Digitalmars-d-learn (22/42) May 12 2017 That's the wrong isNumeric. Unfortunately, both std.string and std.trait...
- k-five (10/35) May 12 2017 -----------------------------------------------------------------
- ag0aep6g (4/8) May 12 2017 If you're doing this for speed, you better be benchmarking. Exceptions
- H. S. Teoh via Digitalmars-d-learn (13/22) May 12 2017 Yes, when it comes to performance-related issues, always profile,
- Jonathan M Davis via Digitalmars-d-learn (34/53) May 13 2017 For the most part, when parsing a string, std.conv.to's approach of just
- k-five (19/39) May 13 2017 Can you please give a link or page or something to read about
- Bastiaan Veelo (11/16) May 13 2017 Profiling:
I have a line of code that uses "to" function in std.conv for a purpose like: int index = to!int( user_apply[ 4 ] ); // string to int When the user_apply[ 4 ] has value, there is no problem; but when it is empty: "" it throws an ConvException exception and I want to avoid this exception. currently I have to use a dummy catch: try{ index = to!int( user_apply[ 4 ] ); } catch( ConvException conv_error ){ // nothing } I no need to handle that, so is there any way to prevent this exception?
May 10 2017
On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:I have a line of code that uses "to" function in std.conv for a purpose like: int index = to!int( user_apply[ 4 ] ); // string to int When the user_apply[ 4 ] has value, there is no problem; but when it is empty: "" it throws an ConvException exception and I want to avoid this exception. currently I have to use a dummy catch: try{ index = to!int( user_apply[ 4 ] ); } catch( ConvException conv_error ){ // nothing } I no need to handle that, so is there any way to prevent this exception?there has been talk of adding an overload that substitutes a supplied value on failure. apart from that there is assumeWontThrow in the stdlib somewhere.
May 10 2017
On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:I have a line of code that uses "to" function in std.conv for a purpose like: int index = to!int( user_apply[ 4 ] ); // string to int When the user_apply[ 4 ] has value, there is no problem; but when it is empty: "" it throws an ConvException exception and I want to avoid this exception. currently I have to use a dummy catch: try{ index = to!int( user_apply[ 4 ] ); } catch( ConvException conv_error ){ // nothing } I no need to handle that, so is there any way to prevent this exception?I assume that an empty string is a valid input then. The question is, what value do you want `index` to have when the string is empty? Maybe the old value, or some constant? In any case, to better express your intent, you may write something like: if (user_apply[4] != "") { index = to !(int) (user_apply[4]); } else { index = ...; // specify whatever your intent is } This way, the code is self-documenting, and the program still throws when `user_apply[4]` is neither empty nor an integer, which may be the right thing to do in the long run. Ivan Kazmenko.
May 10 2017
On Wednesday, 10 May 2017 at 13:12:46 UTC, Ivan Kazmenko wrote:On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:----------------------------------------------------------I assume that an empty string is a valid input then. The question is, what value do you want `index` to have when the string is empty? Maybe the old value, or some constant? In any case, to better express your intent, you may write something like: if (user_apply[4] != "") { index = to !(int) (user_apply[4]); } else { index = ...; // specify whatever your intent is } This way, the code is self-documenting, and the program still throws when `user_apply[4]` is neither empty nor an integer, which may be the right thing to do in the long run. Ivan Kazmenko.---------------------------------------------------------- Thanks, but I know about what are you saying. The user_apply[4] has so many possibilities and I cannot use if-else
May 10 2017
On Wednesday, 10 May 2017 at 13:27:17 UTC, k-five wrote:Thanks, but I know about what are you saying. The user_apply[4] has so many possibilities and I cannot use if-elseThat doesn't sound right. Either you've already handled all the possible cases and thus expect the to! to not throw (can specify that i.e. via std.exception.assumeWontThrow), or, as you're saying, it's much more than an if-else, but in that case exception will be thrown on invalid input.
May 10 2017
On Wednesday, 10 May 2017 at 14:27:46 UTC, Stanislav Blinov wrote:On Wednesday, 10 May 2017 at 13:27:17 UTC, k-five wrote:------------------------------------------------------------------ I know. But I am saying that I do not want to take care of any exceptions. I just wanted to write: int variable = to!int( string-type ); In fact something like using "no throw" is a function: void init( ... ) nothrow { ... int variable = to!int( string-type ); ... } but this is not valid. Thanks anyway and I will test: Function std.exception.assumeWontThrow at this link: https://dlang.org/library/std/exception/assume_wont_throw.htmlThanks, but I know about what are you saying. The user_apply[4] has so many possibilities and I cannot use if-elseThat doesn't sound right. Either you've already handled all the possible cases and thus expect the to! to not throw (can specify that i.e. via std.exception.assumeWontThrow), or, as you're saying, it's much more than an if-else, but in that case exception will be thrown on invalid input.
May 10 2017
On Wednesday, 10 May 2017 at 15:35:24 UTC, k-five wrote:On Wednesday, 10 May 2017 at 14:27:46 UTC, Stanislav Blinov wrote:I don't understand. If you don't want to take care of exceptions, then you just don't do anything, simply call to!int(str). If an exception is thrown, it'll propagate further up the stack, until you either handle it or abort the program. "nothrow" does not turn off exceptions, it simply forbids throwing them in the enclosing scope (i.e. calling anything that might throw is not allowed). Or do you mean that you've already made sure that the user input is valid such that to!int() will never throw with it? In that case, yes, assumeWontThrow is a way to express that. But then, the only way you can be sure of that is if you've already parsed the input yourself, so I'm not clear on the intent. Alternatively, if what you're calling still might throw but you don't want to deal with try/catch blocks, there's collectException function in std.exception that'll give you the exception if it was thrown and let you deal with it without using try/catch.On Wednesday, 10 May 2017 at 13:27:17 UTC, k-five wrote:------------------------------------------------------------------ I know. But I am saying that I do not want to take care of any exceptions. I just wanted to write: int variable = to!int( string-type ); In fact something like using "no throw" is a function: void init( ... ) nothrow { ... int variable = to!int( string-type ); ... } but this is not valid. Thanks anyway and I will test: Function std.exception.assumeWontThrow at this link: https://dlang.org/library/std/exception/assume_wont_throw.htmlThanks, but I know about what are you saying. The user_apply[4] has so many possibilities and I cannot use if-elseThat doesn't sound right. Either you've already handled all the possible cases and thus expect the to! to not throw (can specify that i.e. via std.exception.assumeWontThrow), or, as you're saying, it's much more than an if-else, but in that case exception will be thrown on invalid input.
May 10 2017
On Wednesday, 10 May 2017 at 21:19:21 UTC, Stanislav Blinov wrote:"nothrow" does not turn off exceptions, it simply forbids throwing them in the enclosing scope (i.e. calling anything that might throw is not allowed).nothrow disallows the function scope to throw exceptions not derived from core.object.Error. It makes no claim about what happens *inside* the scope; you can throw as much as you want inside nothrow, as long as you take care to catch anything that's not a core.object.Error (which is what std.exception.assumeWontThrow essentially does).
May 10 2017
On Wednesday, 10 May 2017 at 21:19:21 UTC, Stanislav Blinov wrote:On Wednesday, 10 May 2017 at 15:35:24 UTC, k-five wrote:---------------------------------------------------------------On Wednesday, 10 May 2017 at 14:27:46 UTC, Stanislav BlinovI don't understand. If you don't want to take care of exceptions, then you just don't do anything, simply call to!int(str).Well I did that, but when the string is a valid type like: "10" there is no problems. But when the string is not valid, like: "abc", then to! function throws an exception. Why I do not want to take care of that? Because I just need the value, if the string is valid, otherwise no matter what the value of string is. First I just wrote: index = to!int( user_apply[ 4 ] ); And this code is a part of a command-line program and the user may enter anything. So, for a valid string: ./program '10' // okey but for: ./program 'non-numerical' // throws an exception an 10 lines of error appear on the screen( console ) I just want to silent this exception. Of course it is useful for handling when someone wants to. But in my code I no need to handle it. So I want to silent that, without using try{}catch(){} block. I just wondered about try-catch and I want to know may there would be a better way instead of a dummy try-catch block. Thanks for replying and mentioning. And I am sorry, since I an new in English Writing, if you got confuse.
May 11 2017
On Thursday, 11 May 2017 at 16:07:22 UTC, k-five wrote:On Wednesday, 10 May 2017 at 21:19:21 UTC, Stanislav Blinov wrote:You are not making a lot of sense: 1. Exception do bubble up, so you don't need to "handle" exceptions at the call site if you don't want to. The whole point of exceptions is do effectively do what you want. 2. You say that you don't have to deal with it in your code but you are trying to deal with it now. You are not clear on exactly what you are trying to accomplish. Can you be more specific on why you do not want to add a try/catch/if-else/ifThrown/etc? Is it because you don't need to handle it in your own usage? If that is true, will others ever use it? Basically all you have to do is ask yourself this: "Do I need to EVER handle the case where the data is invalid?" If you do(e.g., other users will use your code) then you better implement some type of exception handling. Else all you have to do is always put in the right data(not good because it might bite you in the ass one day). If you just want less noise when the program crashes, just put a try/catch block in main and catch all generic exceptions and exit with a simple error message like "There was an ERROR, I do not know why...".On Wednesday, 10 May 2017 at 15:35:24 UTC, k-five wrote:---------------------------------------------------------------On Wednesday, 10 May 2017 at 14:27:46 UTC, Stanislav BlinovI don't understand. If you don't want to take care of exceptions, then you just don't do anything, simply call to!int(str).Well I did that, but when the string is a valid type like: "10" there is no problems. But when the string is not valid, like: "abc", then to! function throws an exception. Why I do not want to take care of that? Because I just need the value, if the string is valid, otherwise no matter what the value of string is. First I just wrote: index = to!int( user_apply[ 4 ] ); And this code is a part of a command-line program and the user may enter anything. So, for a valid string: ./program '10' // okey but for: ./program 'non-numerical' // throws an exception an 10 lines of error appear on the screen( console ) I just want to silent this exception. Of course it is useful for handling when someone wants to. But in my code I no need to handle it. So I want to silent that, without using try{}catch(){} block. I just wondered about try-catch and I want to know may there would be a better way instead of a dummy try-catch block. Thanks for replying and mentioning. And I am sorry, since I an new in English Writing, if you got confuse.
May 12 2017
On Saturday, 13 May 2017 at 02:40:17 UTC, Mike B Johnson wrote:You are not making a lot of sense: 1. Exception do bubble up, so you don't need to "handle" exceptions at the call site if you don't want to. The whole point of exceptions is do effectively do what you want. 2. You say that you don't have to deal with it in your code but you are trying to deal with it now. You are not clear on exactly what you are trying to accomplish. Can you be more specific on why you do not want to add a try/catch/if-else/ifThrown/etc? Is it because you don't need to handle it in your own usage? If that is true, will others ever use it? Basically all you have to do is ask yourself this: "Do I need to EVER handle the case where the data is invalid?" If you do(e.g., other users will use your code) then you better implement some type of exception handling. Else all you have to do is always put in the right data(not good because it might bite you in the ass one day). If you just want less noise when the program crashes, just put a try/catch block in main and catch all generic exceptions and exit with a simple error message like "There was an ERROR, I do not know why...".---------------------------------------------------------------- Way arguing when a simple code can clarify the subject? right? If am not clear so consider me as an stupid man, no problem at all. but CAN you please solve it for me? import std.stdio: writeln; import std.conv: to; void main( string[] args ){ string str = "10"; int index; index = to!int( str ); // okay, no exception are thrown str = "some-words"; index = to!int( str ); // problem, an exception is thrown } Please run this code and convert "some-words" to int by using to! function without facing any exception. Thanks
May 13 2017
On Saturday, 13 May 2017 at 08:50:20 UTC, k-five wrote:Way arguing when a simple code can clarify the subject? right? If am not clear so consider me as an stupid man, no problem at all. but CAN you please solve it for me? import std.stdio: writeln; import std.conv: to; void main( string[] args ){ string str = "10"; int index; index = to!int( str ); // okay, no exception are thrown str = "some-words"; index = to!int( str ); // problem, an exception is thrown } Please run this code and convert "some-words" to int by using to! function without facing any exception. ThanksPlease don't take it the wrong way. It just seems that Mike was as confused by your questions as I was initially. But it's clear that's just the language barrier, nothing more. See, you said:Why I do not want to take care of that? Because I just need the value, if the string is valid, otherwise no matter what the value of string is....but it doesn't make sense to have an int "value" for a string like "some-words". *Unless* one defines a "not-a-number" equivalent for an int, i.e. 0 or some other value. That part was hard to infer from what you were saying :) It might've been obvious for you, but hard to understand from what you wrote. This was what made things clear:I just want to silent this exception...Mostly, the source of the confusion was the "I don't want to handle the exception". But in fact what you were asking was was there a way to somehow ignore the exception and just return some predefined value in case of an error. So in fact, you did want to handle the exception (or rather, an exceptional case), you just wanted to do it without inserting control flow instructions (try/catch) into your code. I think the latter part already got covered in others' replies. Nobody was trying to insult you. With this being a multi-lingual and multi-cultural community, remember that understanding goes both ways, and we're sometimes caught right in the middle, in the clash of mentalities.
May 13 2017
On 5/10/17 3:40 PM, k-five wrote:I have a line of code that uses "to" function in std.conv for a purpose like: int index = to!int( user_apply[ 4 ] ); // string to int When the user_apply[ 4 ] has value, there is no problem; but when it is empty: "" it throws an ConvException exception and I want to avoid this exception. currently I have to use a dummy catch: try{ index = to!int( user_apply[ 4 ] ); } catch( ConvException conv_error ){ // nothing } I no need to handle that, so is there any way to prevent this exception?Use the "parse" family: https://dlang.org/phobos/std_conv.html#parse -- Andrei
May 10 2017
On Wednesday, 10 May 2017 at 21:44:32 UTC, Andrei Alexandrescu wrote:On 5/10/17 3:40 PM, k-five wrote:---------------------------------------------------------------------- This is my answer :). I want a way to covert a string without facing any exceptions. But may I do not understand so well the documentation It says: The parse family of functions works quite like the to family, except that: 1 - It only works with character ranges as input. 2 - It takes the input by reference. (This means that rvalues - such as string literals - are not accepted: use to instead.) 3 - It advances the input to the position following the conversion. 4 - It does not throw if it could not convert the entire input. here, number 4: It does not throw if it could not convert the entire input. then it says: Throws: A ConvException if the range does not represent a bool. Well it says different things about throwing! Also I tested this: import std.stdio; import std.conv: parse; void main( string[] args ){ string str = "string"; int index = parse!int( str ); writeln( "index: ", index ); } the output: std.conv.ConvException /usr/include/dmd/phobos/std/conv.d(2111): Unexpected 's' when converting from type string to type int and so on ... Please correct me if I am wrong.I no need to handle that, so is there any way to prevent this exception?Use the "parse" family: https://dlang.org/phobos/std_conv.html#parse -- Andrei
May 11 2017
On 05/10/2017 05:40 AM, k-five wrote:I have a line of code that uses "to" function in std.conv for a purpose like: int index = to!int( user_apply[ 4 ] ); // string to int When the user_apply[ 4 ] has value, there is no problem; but when it is empty: "" it throws an ConvException exception and I want to avoid this exception. currently I have to use a dummy catch: try{ index = to!int( user_apply[ 4 ] ); } catch( ConvException conv_error ){ // nothing }Are you really fine with 'index' being left with its previous value? If so, you can write a function like the following: void setMaybe(To, From)(ref To var, From from) { import std.conv : to, ConvException; try { var = to!To(from); } catch( ConvException conv_error ) { } } unittest { int index = 41; index.setMaybe("42"); assert(index == 42); index.setMaybe("forty three"); assert(index == 42); index.setMaybe(""); assert(index == 42); } void main() { } If you want the variable to be set to a default value (perhaps .init), then here is an idea: void setMaybe(To, From)(ref To var, From from, To def = To.init) { import std.conv : to, ConvException; try { var = to!To(from); } catch( ConvException conv_error ) { var = def; } } unittest { int index = 41; index.setMaybe("42"); assert(index == 42); index.setMaybe("forty three"); assert(index == 0); index.setMaybe(7); index.setMaybe("", 8); assert(index == 8); } void main() { } Ali
May 10 2017
On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:I have a line of code that uses "to" function in std.conv for a purpose like: int index = to!int( user_apply[ 4 ] ); // string to int When the user_apply[ 4 ] has value, there is no problem; but when it is empty: "" it throws an ConvException exception and I want to avoid this exception. currently I have to use a dummy catch: try{ index = to!int( user_apply[ 4 ] ); } catch( ConvException conv_error ){ // nothing } I no need to handle that, so is there any way to prevent this exception?try this: https://dlang.org/phobos/std_exception.html#ifThrown
May 11 2017
On Thursday, 11 May 2017 at 17:18:37 UTC, crimaniak wrote:On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:---------------------------------------------------------try this: https://dlang.org/phobos/std_exception.html#ifThrownWorked. Thanks. import std.stdio; import std.conv: to; import std.exception: ifThrown; void main( string[] args ){ string str = "string"; int index = to!int( str ).ifThrown( 0 ); // if an exception was thrown, it is ignored and then return ( 0 ); writeln( "index: ", index ); // 0 }
May 11 2017
On Thu, May 11, 2017 at 05:55:03PM +0000, k-five via Digitalmars-d-learn wrote:On Thursday, 11 May 2017 at 17:18:37 UTC, crimaniak wrote:Keep in mind, though, that you should not do this in an inner loop if you care about performance, as throwing / catching exceptions will incur a performance hit. Outside of inner loops, though, it probably doesn't matter. T -- Ph.D. = Permanent head DamageOn Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:---------------------------------------------------------try this: https://dlang.org/phobos/std_exception.html#ifThrownWorked. Thanks. import std.stdio; import std.conv: to; import std.exception: ifThrown; void main( string[] args ){ string str = "string"; int index = to!int( str ).ifThrown( 0 ); // if an exception was thrown, it is ignored and then return ( 0 ); writeln( "index: ", index ); // 0 }
May 11 2017
On Thursday, 11 May 2017 at 18:07:47 UTC, H. S. Teoh wrote:On Thu, May 11, 2017 at 05:55:03PM +0000, k-five via Digitalmars-d-learn wrote:This reason is why I sometimes use isNumeric if I have heaps of strings I need to convert, to reduce exceptions. So something like: int index = (str.isNumeric) ? to!int(str).ifThrown(0) : 0; JordanOn Thursday, 11 May 2017 at 17:18:37 UTC, crimaniak wrote:Keep in mind, though, that you should not do this in an inner loop if you care about performance, as throwing / catching exceptions will incur a performance hit. Outside of inner loops, though, it probably doesn't matter. TOn Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:---------------------------------------------------------try this: https://dlang.org/phobos/std_exception.html#ifThrownWorked. Thanks. import std.stdio; import std.conv: to; import std.exception: ifThrown; void main( string[] args ){ string str = "string"; int index = to!int( str ).ifThrown( 0 ); // if an exception was thrown, it is ignored and then return ( 0 ); writeln( "index: ", index ); // 0 }
May 11 2017
On Thursday, 11 May 2017 at 19:59:55 UTC, Jordan Wilson wrote:On Thursday, 11 May 2017 at 18:07:47 UTC, H. S. Teoh wrote:-------------------------------------------------------------- Interesting! I was worried about performance and for that I did not want to use try-catch. So (isNumberic) is a good solution. http://dlang.org/phobos/std_traits.html#isNumericOn Thu, May 11, 2017 at 05:55:03PM +0000, k-five via Digitalmars-d-learn wrote:This reason is why I sometimes use isNumeric if I have heaps of strings I need to convert, to reduce exceptions. So something like: int index = (str.isNumeric) ? to!int(str).ifThrown(0) : 0; JordanOn Thursday, 11 May 2017 at 17:18:37 UTC, crimaniak wrote:On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:---------------------------------------------------------
May 12 2017
On Friday, 12 May 2017 at 08:32:03 UTC, k-five wrote:On Thursday, 11 May 2017 at 19:59:55 UTC, Jordan Wilson wrote:---------------------------------------------------------------- NOT a GOOD solution! Since it accept type and NOT variable: so: index = (str.isNumeric) ? to!int(str).ifThrown(0) : 0; is: temp.d(11): Error: template std.traits.isNumeric cannot deduce function from argument types !()(string), candidates are:On Thursday, 11 May 2017 at 18:07:47 UTC, H. S. Teoh wrote:-------------------------------------------------------------- Interesting! I was worried about performance and for that I did not want to use try-catch. So (isNumberic) is a good solution. http://dlang.org/phobos/std_traits.html#isNumericOn Thu, May 11, 2017 at 05:55:03PM +0000, k-five via Digitalmars-d-learn wrote:This reason is why I sometimes use isNumeric if I have heaps of strings I need to convert, to reduce exceptions. So something like: int index = (str.isNumeric) ? to!int(str).ifThrown(0) : 0; JordanOn Thursday, 11 May 2017 at 17:18:37 UTC, crimaniak wrote:On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:---------------------------------------------------------
May 12 2017
On Friday, May 12, 2017 08:32:03 k-five via Digitalmars-d-learn wrote:On Thursday, 11 May 2017 at 19:59:55 UTC, Jordan Wilson wrote:That's the wrong isNumeric. Unfortunately, both std.string and std.traits have an isNumeric. std.traits.isNumeric is an eponymous template that tests whether a type is an integral or floating point type, whereas std.string.isNumeric is a templated function which tests whether a string (or other range of characters) represents an integer or floating point literal. So, std.traits.isNumeric won't work at all for what you want, and std.string.isNumeric will sort of do what you want - the main caveat being that it will also accept floating point values, whereas to!int will not. So, if you have auto i = str.isNumeric ? to!int(str).ifThrown(0) : 0; then it will work but will still throw (and then be caught by ifThrown) if str is a floating point value. Alternatively, you could check something like auto i = str.all!isDigit ? to!int(str).ifThrown(0) : 0; (where all is in std.algorithm and isDigit is in std.ascii), and that _almost_ wouldn't need ifThrown, letting you do auto i = str.all!isDigit ? to!int(str) : 0; except that str could be an integral value that wouldn't fit in an int, in which case to!int would throw. But std.string.isNumeric will work so long as you're willing to have have an exception be thrown and caught if the string is a floating point literal. - Jonathan M DavisOn Thursday, 11 May 2017 at 18:07:47 UTC, H. S. Teoh wrote:-------------------------------------------------------------- Interesting! I was worried about performance and for that I did not want to use try-catch. So (isNumberic) is a good solution. http://dlang.org/phobos/std_traits.html#isNumericOn Thu, May 11, 2017 at 05:55:03PM +0000, k-five via Digitalmars-d-learn wrote:This reason is why I sometimes use isNumeric if I have heaps of strings I need to convert, to reduce exceptions. So something like: int index = (str.isNumeric) ? to!int(str).ifThrown(0) : 0; JordanOn Thursday, 11 May 2017 at 17:18:37 UTC, crimaniak wrote:On Wednesday, 10 May 2017 at 12:40:41 UTC, k-five wrote:---------------------------------------------------------
May 12 2017
On Friday, 12 May 2017 at 09:03:39 UTC, Jonathan M Davis wrote:That's the wrong isNumeric. Unfortunately, both std.string and std.traits have an isNumeric. std.traits.isNumeric is an eponymous template that tests whether a type is an integral or floating point type, whereas std.string.isNumeric is a templated function which tests whether a string (or other range of characters) represents an integer or floating point literal. So, std.traits.isNumeric won't work at all for what you want, and std.string.isNumeric will sort of do what you want - the main caveat being that it will also accept floating point values, whereas to!int will not. So, if you have auto i = str.isNumeric ? to!int(str).ifThrown(0) : 0; then it will work but will still throw (and then be caught by ifThrown) if str is a floating point value. Alternatively, you could check something like auto i = str.all!isDigit ? to!int(str).ifThrown(0) : 0; (where all is in std.algorithm and isDigit is in std.ascii), and that _almost_ wouldn't need ifThrown, letting you do auto i = str.all!isDigit ? to!int(str) : 0; except that str could be an integral value that wouldn't fit in an int, in which case to!int would throw. But std.string.isNumeric will work so long as you're willing to have have an exception be thrown and caught if the string is a floating point literal. - Jonathan M Davis----------------------------------------------------------------- Thank you for mentioning it. Since I had seen D-conference 2016 in YouTube and it talked about isNumeric in std.traits, then I used std.traits. and does not worked as I wanted. But std.string: isNumeric, worked. string str = "string"; int index = str.isNumeric ? to!int( str ) : 0; writeln( "index: ", index ); // 0 and without throwing any exceptions
May 12 2017
On 05/12/2017 10:32 AM, k-five wrote:Interesting! I was worried about performance and for that I did not want to use try-catch. So (isNumberic) is a good solution. http://dlang.org/phobos/std_traits.html#isNumericIf you're doing this for speed, you better be benchmarking. Exceptions are slow when they're thrown. But if no exception is being thrown, try-catch is probably faster than checking isNumeric beforehand.
May 12 2017
On Fri, May 12, 2017 at 12:47:04PM +0200, ag0aep6g via Digitalmars-d-learn wrote:On 05/12/2017 10:32 AM, k-five wrote:Yes, when it comes to performance-related issues, always profile, profile, profile. (Or benchmark, benchmark, benchmark. Anything that gives you actual measurements rather than subjective judgment calls.) Far too often, what we think will perform poorly is actually nowhere near the real bottleneck in the program, and we end up wasting too much time "optimizing" something that doesn't even make a noticeable difference in the end. Whereas, using a profiler early on will help you zero in on the real bottlenecks, and you could potentially make huge performance savings with much less effort. T -- Beware of bugs in the above code; I have only proved it correct, not tried it. -- Donald KnuthInteresting! I was worried about performance and for that I did not want to use try-catch. So (isNumberic) is a good solution. http://dlang.org/phobos/std_traits.html#isNumericIf you're doing this for speed, you better be benchmarking. Exceptions are slow when they're thrown. But if no exception is being thrown, try-catch is probably faster than checking isNumeric beforehand.
May 12 2017
On Friday, May 12, 2017 10:42:18 H. S. Teoh via Digitalmars-d-learn wrote:On Fri, May 12, 2017 at 12:47:04PM +0200, ag0aep6g via Digitalmars-d-learnwrote:For the most part, when parsing a string, std.conv.to's approach of just parsing the string and throwing an exception if/when it fails is the most efficient, because it's only going to parse the string once, whereas calling a function to validate the string's format and _then_ do the conversion would mean parsing the string twice. It's just that if you are in a situation where the string is likely not to be in the correct format, then having a bunch of exceptions thrown will harm performance. To best handle that, we'd need an alternate conversion function that did something like return the failure condition and passed the result via an out parameter or one which took a default value and returned that on failure instead of what was actaully parsed. So, ideally, we'd have other functions in std.conv to handle such cases, but in the vast majority of cases, throwing an exception on failure is going to be the most efficient solution. But obviously, to know what's actually happening with your code, you're going to have to profile and benchmark it - especially if you're throwing exceptions on a regular basis but not super frequently, because then it's quickly an open question as to whether parsing twice to avoid the exception or letting the exception be thrown and caught would be faster. Odds are though that unless you're converting in a tight loop, the relative costs won't matter much, even if one is clearly more expensive than the other, simply because it's not a bottleneck in your program. But you won't know that for sure unless you profile. However, unless you're parsing a lot of invalid strings, I'd be very surprised if always parsing twice were more efficient than parsing only once and throwing an exception on failure. And D exceptions are fairly efficient at this point if you don't call toString, because we stripped out most of the string processing that they were doing up front before. It used to be pretty painful when you did a lot of tests that tested the error cases, because the exceptions really increased the time that the tests took, but that's no longer the case (IIRC, the improvements literally saved seconds of execution time in std.datetime's unit tests). - Jonathan M DavisOn 05/12/2017 10:32 AM, k-five wrote:Yes, when it comes to performance-related issues, always profile, profile, profile. (Or benchmark, benchmark, benchmark. Anything that gives you actual measurements rather than subjective judgment calls.) Far too often, what we think will perform poorly is actually nowhere near the real bottleneck in the program, and we end up wasting too much time "optimizing" something that doesn't even make a noticeable difference in the end. Whereas, using a profiler early on will help you zero in on the real bottlenecks, and you could potentially make huge performance savings with much less effort.Interesting! I was worried about performance and for that I did not want to use try-catch. So (isNumberic) is a good solution. http://dlang.org/phobos/std_traits.html#isNumericIf you're doing this for speed, you better be benchmarking. Exceptions are slow when they're thrown. But if no exception is being thrown, try-catch is probably faster than checking isNumeric beforehand.
May 13 2017
On Saturday, 13 May 2017 at 09:05:17 UTC, Jonathan M Davis wrote:For the most part, when parsing a string, std.conv.to's approach of just parsing the string and throwing an exception if/when it fails is the most efficient, because it's only going to parse the string once, whereas calling a function to validate the string's format and _then_ do the conversion would mean parsing the string twice.It's just that if you are in a situation where the string is likely not to be in the correct format, then having a bunch of exceptions thrown will harm performance. To best handle that, we'd need an alternate conversion function that did something like return the failure condition and passed the result via an out parameter or one which took a default value and returned that on failure instead of what was actaully parsed. So, ideally, we'd have other functions in std.conv to handle such cases, but in the vast majority of cases, throwing an exception on failure is going to be the most efficient solution.I did not know this.But obviously, to know what's actually happening with your code, you're going to have to profile and benchmark it -Can you please give a link or page or something to read about profile or benchmark. I have no experience with those. ------------------------------------------------------------------- For a such purpose I already used std::stringstream in C++, and I assumed may or may not D has a such family. ( to!, parse!, ... ) Not only an invalid string like "word" for to!int, makes it being thrown, but an empty string like: "" also makes it. string str = "word"; int index = to!int( str ); // throws str = ""; int index = to!int( str ); // throws, as well! Of course throwing is useful some times, but definitely not ALWAYS, and it is better to have a convert function that never throws anything. Although [Andrei Alexandrescu] told me that the parse! family is used for such a case:Use the "parse" family: https://dlang.org/phobos/std_conv.html#parse -- Andreibut it throws as well.
May 13 2017
On Saturday, 13 May 2017 at 09:51:40 UTC, k-five wrote:On Saturday, 13 May 2017 at 09:05:17 UTC, Jonathan M DavisProfiling: Halfway down this page: http://www.digitalmars.com/ctg/trace.html Two programs for visualising bottlenecks: https://bitbucket.org/andrewtrotman/d-profile-viewer https://code.dlang.org/packages/profdump Benchmarking: https://youtu.be/QELK73JSpFk?list=PL3jwVPmk_PRxo23yyoc0Ip_cP3-rCm7eB (fresh from DConf) https://dlang.org/library/std/datetime/benchmark.html https://code.dlang.org/packages/std_benchmark https://code.dlang.org/packages/benchmarkplotterBut obviously, to know what's actually happening with your code, you're going to have to profile and benchmark it -Can you please give a link or page or something to read about profile or benchmark. I have no experience with those.
May 13 2017