Raku / user-experience

Identifying issues in and improving the Raku user experience
Artistic License 2.0
25 stars 5 forks source link

LTA, missing dynamic does not throw but return Failure #48

Closed MARTIMM closed 1 year ago

MARTIMM commented 1 year ago

I made an error using a dynamic variable which was removed from my code. A simplified version where it takes place looks like this

$hash{entry} = $*abc<d>;

The variable $*abc is not declared before. The result of this is that a Failure object is stored and a crash takes place somewhere else when accessed. In my case deep down in YAMLish when I wanted to store the data and therefore very difficult to find the particular location in the data.

Examples showing the problem. The first seems to be alright, and the second throws because say wants to use it

> raku -e 'my Hash $h = %(); $h<b> = $*abc<d>;'
> raku -e 'my Hash $h = %(); $h<b> = $*abc<d>; say $h'
Dynamic variable $*abc not found
  in block <unit> at -e line 1

Perhaps it is better to throw it as soon it is obvious that there is no dynamic declared like any other type of variable.

vrurg commented 1 year ago

This change is barely possible because one of the widely used way of using dynamics is: my $option = $*MY-OPTION // $default-option;. Changing to the immediate error not only would break this behavior immediately but the workaround will require a try which is way more expensive.

MARTIMM commented 1 year ago

Thanks for your answer, I understand that the workaround is not good either. I had this misunderstanding that an undeclared variable also throws errors, but I see now that that is caused while compiling the source and that the dynamic variable is missing at run time so it needs different handling.

In the end, I've learned from it and can also check for this type of problem. Your example shows that there can be a different setting depending on which caller has set the dynamic beforehand.

raiph commented 1 year ago

Fwiw there's a pragma which might be helpful:

use fatal;
my Hash $h = %();
$h<b> = $*abc<d>; 

displays:

Dynamic variable $*abc not found
  in block <unit> at main.raku line 3
vrurg commented 1 year ago

@raiph Thanks, very good point!

@MARTIMM I'm closing this for now. Feel free to re-open if something is missed.