From a421337b628532d5fd8c601fb88f88541970e53a Mon Sep 17 00:00:00 2001 From: Ezio Date: Mon, 24 Apr 2017 04:45:19 +0800 Subject: [PATCH] =?UTF-8?q?20170423-4=20=E9=80=89=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/tech/20170422 The root of all eval.md | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 sources/tech/20170422 The root of all eval.md diff --git a/sources/tech/20170422 The root of all eval.md b/sources/tech/20170422 The root of all eval.md new file mode 100644 index 0000000000..75077d1a81 --- /dev/null +++ b/sources/tech/20170422 The root of all eval.md @@ -0,0 +1,66 @@ +[The root of all eval][1] +============================================================ + +Ah, the `eval` function. Loved, hated. Mostly the latter. + +``` +$ perl -E'my $program = q[say "OH HAI"]; eval $program' +OH HAI +``` + +I was a bit stunned when the `eval` function was renamed to `EVAL` in Perl 6 (back in 2013, after spec discussion [here][2]). I've never felt really comfortable with the rationale for doing so. I seem to be more or less alone in this opinion, though, which is fine. + +The rationale was "the function does something really weird, so we should flag it with upper case". Like we do with `BEGIN` and the other phasers, for example. With `BEGIN` and others, the upper-casing is motivated, I agree. A phaser takes you "outside of the normal control flow". The `eval` function doesn't. + +Other things that we upper-case are things like `.WHAT`, which look like attributes but are really specially code-generated at compile-time into something completely different. So even there the upper-casing is motivated because something outside of the normal is happening. + +`eval` in the end is just another function. Yes, it's a function with potentially quite wide-ranging side effects, that's true. But a lot of fairly standard functions have wide-ranging side effects. (To name a few: `shell`, `die`, `exit`.) You don't see anyone clamoring to upper-case those. + +I guess it could be argued that `eval` is very special because it hooks into the compiler and runtime in ways that normal functions don't, and maybe can't. (This is also how TimToady explained it in [the commit message][3] of the renaming commit.) But that's an argument from implementation details, which doesn't feel satisfactory. It applies with equal force to the lower-cased functions just mentioned. + +To add insult to injury, the renamed `EVAL` is also made deliberately harder to use: + +``` +$ perl6 -e'my $program = q[say "OH HAI"]; EVAL $program' +===SORRY!=== Error while compiling -e +EVAL is a very dangerous function!!! (use the MONKEY-SEE-NO-EVAL pragma to override this error, +but only if you're VERY sure your data contains no injection attacks) +at -e:1 +------> program = q[say "OH HAI"]; EVAL $program⏏ + +$ perl6 -e'use MONKEY-SEE-NO-EVAL; my $program = q[say "OH HAI"]; EVAL $program' +OH HAI +``` + +Firstly, injection attacks are a real issue, and no laughing matter. We should educate each other and newcomers about them. + +Secondly, that error message (`"EVAL is a very dangerous function!!!"`) is completely over-the-top in a way that damages rather than helps. I believe when we explain the dangers of code injection to people, we need to do it calmly and matter-of-factly. Not with three exclamation marks. The error message makes sense to [someone who already knows about injection attacks][4]; it provides no hints or clues for people who are unaware of the risks. + +(The Perl 6 community is not unique in `eval`-hysteria. Yesterday I stumbled across a StackOverflow thread about how to turn a string with a type name into the corresponding constructor in JavaScript. Some unlucky soul suggested `eval`, and everybody else immediately piled on to point out how irresponsible that was. Solely as a knee-jerk reaction "because eval is bad".) + +Thirdly, `MOKNEY-SEE-NO-EVAL`. Please, can we just... not. 😓 Random reference to monkies and the weird attempt at levity while switching on a nuclear-chainsaw function aside, I find it odd that a function that  _enables_  `EVAL` is called something with `NO-EVAL`. That's not Least Surprise. + +Anyway, the other day I realized how I can get around both the problem of the all-caps name and the problem of the necessary pragma: + +``` +$ perl6 -e'my &eval = &EVAL; my $program = q[say "OH HAI"]; eval $program' +OH HAI +``` + +I was so happy to realize this that I thought I'd blog about it. Apparently the very dangerous function (`!!!`) is fine again if we just give it back its old name. 😜 + +-------------------------------------------------------------------------------- + +via: http://strangelyconsistent.org/blog/the-root-of-all-eval + +作者:[Carl Mäsak ][a] +译者:[译者ID](https://github.com/译者ID) +校对:[校对者ID](https://github.com/校对者ID) + +本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 + +[a]:http://strangelyconsistent.org/about +[1]:http://strangelyconsistent.org/blog/the-root-of-all-eval +[2]:https://github.com/perl6/specs/issues/50 +[3]:https://github.com/perl6/specs/commit/0b7df09ecc096eed5dc30f3dbdf568bbfd9de8f6 +[4]:http://bobby-tables.com/