Re: How to capture an div 0 exception

2016-05-18 Thread Richard Hainsworth

On Wednesday, May 18, 2016 11:40 PM, Brandon Allbery wrote:
On Wed, May 18, 2016 at 11:29 AM, Brandon Allbery > wrote:


On Wed, May 18, 2016 at 11:27 AM, mt1957 > wrote:

This has something to do with lazy evaluation. It triggers the
calculation when it wants to show the value in $r.


IIRC it doesn't throw, it returns a Failure (deferred/lazy
exception that throws when accessed).


And, since this does not seem to be documented in obvious places yet: 
"use fatal;" pragma changes these lazy exceptions to strict ones.
"use fatal;" does not change the behaviour. The Failure is only thrown 
when referred to. But if the reference is outside the block that 
contains the CATCH block to trap the error, then the error is not caught.

The problem is something like:

{ #some code ...
{ # block with error prone code
# Failure created
# no statement like 'say' to get the failure thrown
CATCH { # code to trap error
}
} # end of block with error prone code
# more code
say  ; # code that causes the Failure to throw an exception
}

Since the exception is thrown outside the block with the CATCH block, it 
is not caught.


How can the lazy / deferred Failure be trapped?

A suggestion:
Would it be possible to implement a C( try ) block so that it forces all 
Failures to throw Exceptions that can be caught in the CATCH?


If it is necessary to have blocks with an explicit CATCH to have 
deferred exceptions, then this behaviour could be kept for ordinary 
blocks, whilst try blocks force the exception.


For the code I was originally working on, which was for arithmetic 
expressions, a work around is to coerce to Num. But it seems to me this 
is not a general solution.


use fatal;
my $r;
for 0..4 -> $s {
   try {
 $r = 5 / (3 - $s);
 CATCH {
   when X::Numeric::DivideByZero { $r = 65 }
   default { $r = 55 }
 }
}
say "At line $?LINE r is $r";
}
## results in
At line 11 r is 1.67
At line 11 r is 2.5
At line 11 r is 5
Attempt to divide 5 by zero using div
  in block  at test.pl line 11

Actually thrown at:
  in block  at test.pl line 11

### But
my $r;
for 0..4 -> $s {
 $r = (5 / (3 - $s)).Num;
say "At line $?LINE r is $r";
}
 results in
At line 4 r is 1.67
At line 4 r is 2.5
At line 4 r is 5
At line 4 r is Inf
At line 4 r is -5



Re: How to capture an div 0 exception

2016-05-18 Thread mt1957

Hi Richard,

This has something to do with lazy evaluation. It triggers the 
calculation when it wants to show the value in $r. So commenting out the 
first 'say' will error on the second with the shown response. The CATCH 
is not at the same scope than the second 'say' statement so there you 
get a different action.


Something interesting might be when changing the expression into '$r = 5 
/ (3 - $s).Num;' You get a different response and you will not need the 
CATCH at all. Just test on Inf if you need to change it.


An example;

use v6;

my $r;
for 0..4 -> $s {
   $r = (5 / (3 - $s));
   $r = 42 if $r.Num ~~ Inf;

   say "At line $?LINE r is $r";
}

Response

At line 10 r is 1.67
At line 10 r is 2.5
At line 10 r is 5
At line 10 r is 42
At line 10 r is -5

Greetings,
Marcel


Marcel and Moritz,

Thank you for the fast response.

I have been experimenting with the code you sent, but still do not
understand something. To illustrate, here is another snippet:
use v6;
my $r;
for 0..4 -> $s {
   {
 $r = 5 / (3 - $s);
 say "At line $?LINE r is $r";
 CATCH {
   when X::Numeric::DivideByZero { $r = 65 }
   default { $r = 55 }
 }
}
say "At line $?LINE r is $r";
}
### result is
At line 6 r is 1.67
At line 12 r is 1.67
At line 6 r is 2.5
At line 12 r is 2.5
At line 6 r is 5
At line 12 r is 5
At line 12 r is 65
At line 6 r is -5
At line 12 r is -5

 However,
use v6;
my $r;
for 0..4 -> $s {
   {
 $r = 5 / (3 - $s);
 say "At line $?LINE r is $r";
 CATCH {
   when X::Numeric::DivideByZero { $r = 65 }
   default { $r = 55 }
 }
}
say "At line $?LINE r is $r";
}
 result is
At line 12 r is 1.67
At line 12 r is 2.5
At line 12 r is 5
Attempt to divide 5 by zero using div
  in block  at test.pl line 12

Actually thrown at:
  in block  at test.pl line 12

It seems that the commented out 'say' statement is required to get the
CATCH statement to "trigger".
a) Why is the exception not caught the assignment statement?
b) What other statement (NO OP) can I use in place of the commented
out 'say' statement?

Clearly, I do not have a good understanding of the Exception
mechanism. Your help in understanding is appreciated.

Richard





Re: How to capture an div 0 exception

2016-05-18 Thread Richard Hainsworth

Marcel and Moritz,

Thank you for the fast response.

I have been experimenting with the code you sent, but still do not 
understand something. To illustrate, here is another snippet:

use v6;
my $r;
for 0..4 -> $s {
   {
 $r = 5 / (3 - $s);
 say "At line $?LINE r is $r";
 CATCH {
   when X::Numeric::DivideByZero { $r = 65 }
   default { $r = 55 }
 }
}
say "At line $?LINE r is $r";
}
### result is
At line 6 r is 1.67
At line 12 r is 1.67
At line 6 r is 2.5
At line 12 r is 2.5
At line 6 r is 5
At line 12 r is 5
At line 12 r is 65
At line 6 r is -5
At line 12 r is -5

 However,
use v6;
my $r;
for 0..4 -> $s {
   {
 $r = 5 / (3 - $s);
 say "At line $?LINE r is $r";
 CATCH {
   when X::Numeric::DivideByZero { $r = 65 }
   default { $r = 55 }
 }
}
say "At line $?LINE r is $r";
}
 result is
At line 12 r is 1.67
At line 12 r is 2.5
At line 12 r is 5
Attempt to divide 5 by zero using div
  in block  at test.pl line 12

Actually thrown at:
  in block  at test.pl line 12

It seems that the commented out 'say' statement is required to get the 
CATCH statement to "trigger".

a) Why is the exception not caught the assignment statement?
b) What other statement (NO OP) can I use in place of the commented out 
'say' statement?


Clearly, I do not have a good understanding of the Exception mechanism. 
Your help in understanding is appreciated.


Richard