4 ms·
"It's just a normal function." No, it has magical access to the lexical scope.
by malft 9y ago
"It's just a normal function." No, it has magical access to the lexical scope.
- kazinator 9y agoIf eval appears to have same access if defined like in the article: my &eval = &EVAL then that is largely moot.
- hyperpape 9y agoIts possible that's a bug and not an intentional design decision. I certainly hope it is, because I agree with you that it doesn't make sense to hide it behind a pragma but have this workaround.
- adrianm 9y agoIsn't eval required to run in the null lexical environment? Or is that only true in Lisp?
- simcop2387 9y agoNo, 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).
- kazinator 9y agoWouldn'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).
- simcop2387 9y agoSo 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 https://perlbot.pl/pastebin/pl5u9w
- hdhzy 9y agoIn JavaScript it depends on how it is invoked: eval(a) has access to scope variables but x=eval;x(a) does not.
- Gaelan 9y agoI am surprised that JavaScript can still surprise me.
- hdhzy 9y agoI suggest reading the spec. 5.1 [0] although dated is written in very easy to understand language (well, most parts). After that, fragments like this suddenly make sense: n = 1 /1*"\/\//.test(n + '"//') [0]: https://www.ecma-international.org/ecma-262/5.1/ https://www.ecma-international.org/ecma-262/5.1/
- Gaelan 9y agoMy favorite bit of wat.js is this: [1,2,3] + [4,5,6] // => "1,2,34,5,6" I mean, it makes some degree of logical sense (toString -> concat) but there is no reason that would ever be the intended behavior. As for that expression, meh. You can write intentionally obtuse code in any language. The problem with JS is the behavior that is different from what you'd expect.