Hacker News new | ask | show | jobs
by simcop2387 3349 days ago
No, in perl eval explicitly has access to the local scope. This is used for capturing otherwise fatal errors in perl (it can be used similarly to try/catch).
1 comments

Wouldn't the handlers for exception handling by dynamically scoped, not lexically?

If we have a try block, and call a function, and if that function throws, we want the try block to be able to catch that. The function is not understood as having magic access to an environment; it's a pervasive dynamic environment that is visible to the current execution context at all times, in which exit points for non-local transfers are established.

That's almost the entire point since an error situation that is entirely confined to a lexical scope can be dealt with using some local control flow (some form of goto, or structured derivative thereof).

So with perl 5 there isn't a real exception handler like you'd expect from other languages (I'm unsure of perl 6). It works like the following (program output available at [1]):

    use v5.24.0;
    my $x = 1;
    my $y = "bar";
    
    sub foo { # this sub fails fatally
       die "what is going on here";
    }
    
    say "x is $x, y is $y"; # 1 and bar
    
    eval { # similar to try
      my $y = "baz"; # we have a new lexical scope in here too.
      $x = 2; # but this will change the outside scope since it's also available to us
      say "x is $x, y is $y"; # 2 and baz
      foo();
      $x = 3; # this never happens
    };
    
    if ($@) { # check for an error, similar to catch
       say "CAUGHT ERROR: ", $@; # just parrot the error out for now.
    }
    
    say "x is $x, y is $y"; # 2 and bar
Inside the eval the lexical scope outside is still available and a new one is also available. The error that happens gets stuffed into a special variable and you can choose to handle it or not later. This works the same way if you give eval a string to run also.

[1] https://perlbot.pl/pastebin/pl5u9w