Loading ...
Sorry, an error occurred while loading the content.

This eval is not evil

Expand Messages
  • Felix E. Klee
    For the following code, JSLint returns eval is evil. : /*jslint node: true */ use strict ; var client = require( redis ).createClient();
    Message 1 of 10 , Oct 12, 2012
    • 0 Attachment
      For the following code, JSLint returns "eval is evil.":

      /*jslint node: true */
      'use strict';
      var client = require('redis').createClient();
      client['eval']("return 100.5", 0, function (err, res) {
      console.dir(err);
      console.dir(res);
      });

      However, this "eval" has nothing to do with the evil function built into
      JavaScript.
    • Felix E. Klee
      ... It returns a client object, allowing interfacing with the [Redis key-value store][1]. ... Look at the comment at the top of the code: It s Node.js code,
      Message 2 of 10 , Oct 16, 2012
      • 0 Attachment
        > require('redis').createClient() returns type Object or the like

        It returns a client object, allowing interfacing with the [Redis
        key-value store][1].

        > you assume that this code will only be run in environments that
        > support console

        Look at the comment at the top of the code: It's Node.js code, which is
        based on the [V8 JavaScript engine][2]. `console` is available.

        > First createClient is deprecated in node.js.

        `createClient` is not a Node.js function; it is part of the [Redis
        client for Node.js][3]; it is not deprecated.

        > Secondly the 'eval' property on client is just a mutation of the eval
        > function/operator as present in JavaScript (it simply has more ),

        No. This exposes Redis' EVAL command. From the [documentation][4]:

        "EVAL and EVALSHA are used to evaluate scripts using the Lua interpreter
        built into Redis [...]"

        [1]: http://redis.io/
        [2]: http://code.google.com/p/v8/
        [3]: https://github.com/mranney/node_redis
        [4]: http://redis.io/commands/eval
      • douglascrockford
        ... /*jslint evil: true */
        Message 3 of 10 , Oct 18, 2012
        • 0 Attachment
          --- In jslint_com@yahoogroups.com, "Felix E. Klee" <felix.klee@...> wrote:

          > For the following code, JSLint returns "eval is evil.":
          >
          > /*jslint node: true */
          > 'use strict';
          > var client = require('redis').createClient();
          > client['eval']("return 100.5", 0, function (err, res) {
          > console.dir(err);
          > console.dir(res);
          > });
          >
          > However, this "eval" has nothing to do with the evil function built into
          > JavaScript.


          /*jslint evil: true */
        • Felix E. Klee
          On Thu, Oct 18, 2012 at 9:05 AM, douglascrockford ... I am already using that comment, but it is misleading, because: This eval is not evil.
          Message 4 of 10 , Oct 18, 2012
          • 0 Attachment
            On Thu, Oct 18, 2012 at 9:05 AM, douglascrockford
            <douglas@...> wrote:
            > /*jslint evil: true */

            I am already using that comment, but it is misleading, because: This
            eval is not evil.
          • douglascrockford
            ... How do you expect JSLint to know that?
            Message 5 of 10 , Oct 18, 2012
            • 0 Attachment
              --- In jslint_com@yahoogroups.com, "Felix E. Klee" <felix.klee@...> wrote:
              >
              > On Thu, Oct 18, 2012 at 9:05 AM, douglascrockford
              > <douglas@...> wrote:
              > > /*jslint evil: true */
              >
              > I am already using that comment, but it is misleading, because: This
              > eval is not evil.


              How do you expect JSLint to know that?
            • Felix E. Klee
              On Thu, Oct 18, 2012 at 2:02 PM, douglascrockford ... By checking the object: `eval`, `window.eval`, `global.eval`, etc. are evil Of course, it could be that
              Message 6 of 10 , Oct 18, 2012
              • 0 Attachment
                On Thu, Oct 18, 2012 at 2:02 PM, douglascrockford
                <douglas@...> wrote:
                >> This eval is not evil.
                >
                > How do you expect JSLint to know that?

                By checking the object: `eval`, `window.eval`, `global.eval`, etc. are
                evil

                Of course, it could be that somewhere, eval is reassigned to another
                object `x`:

                x.eval = eval;

                But so it could be that somewhere:

                x.f = eval;

                There is no perfect check, and every unknown (to JSLint) function could
                potentially be `eval`. Well, perhaps that's your point, and I should
                just amend the JSLint comment to tell other programmers what is
                happening here.
              • Marcel Duran
                Of course eval can be disguised in several ways, such as: window[ eval .toString()]( alert( foobar ) ); So your redis client could be:
                Message 7 of 10 , Oct 18, 2012
                • 0 Attachment
                  Of course eval can be disguised in several ways, such as:

                  window['eval'.toString()]('alert("foobar")');

                  So your redis client could be:

                  client['eval'.toString()]("return 100.5", 0, function (err, res) {

                  and avoid jslint evil: true option

                  @marcelduran


                  On Thu, Oct 18, 2012 at 5:35 AM, Felix E. Klee <felix.klee@...> wrote:

                  > **
                  >
                  >
                  > On Thu, Oct 18, 2012 at 2:02 PM, douglascrockford
                  > <douglas@...> wrote:
                  > >> This eval is not evil.
                  > >
                  > > How do you expect JSLint to know that?
                  >
                  > By checking the object: `eval`, `window.eval`, `global.eval`, etc. are
                  > evil
                  >
                  > Of course, it could be that somewhere, eval is reassigned to another
                  > object `x`:
                  >
                  > x.eval = eval;
                  >
                  > But so it could be that somewhere:
                  >
                  > x.f = eval;
                  >
                  > There is no perfect check, and every unknown (to JSLint) function could
                  > potentially be `eval`. Well, perhaps that's your point, and I should
                  > just amend the JSLint comment to tell other programmers what is
                  > happening here.
                  >
                  >
                  >


                  [Non-text portions of this message have been removed]
                • Kirk Cerny
                  I think this eval is evil. I believe that it is close enough to a reserved word to avoid using it as a property name. I also think it makes the code harder to
                  Message 8 of 10 , Oct 18, 2012
                  • 0 Attachment
                    I think this eval is evil.
                    I believe that it is close enough to a reserved word to avoid using it as a
                    property name.

                    I also think it makes the code harder to read and understand, because
                    whenever I read eval
                    any where my first impression is that it is the eval function.
                    I am required to change what my initial first glance assumption tells me.

                    Kirk Cerny


                    [Non-text portions of this message have been removed]
                  • Felix E. Klee
                    On Thu, Oct 18, 2012 at 6:46 PM, Marcel Duran ... Interesting hack, but I don t think this improves readability. Anyways, it s easier
                    Message 9 of 10 , Oct 18, 2012
                    • 0 Attachment
                      On Thu, Oct 18, 2012 at 6:46 PM, Marcel Duran <marcelduran@...>
                      wrote:
                      > client['eval'.toString()]("return 100.5", 0, function (err, res) {

                      Interesting hack, but I don't think this improves readability.

                      Anyways, it's easier to just use alternative names:

                      client.EVAL

                      All Redis commands can be passed to the client either in all lowercase
                      or all uppercase.
                    • Felix E. Klee
                      On Thu, Oct 18, 2012 at 7:22 PM, Kirk Cerny ... What s bad about using reserved words as property names? In his book, Douglas mentions
                      Message 10 of 10 , Oct 18, 2012
                      • 0 Attachment
                        On Thu, Oct 18, 2012 at 7:22 PM, Kirk Cerny <kirksemail@...>
                        wrote:
                        > I believe that it is close enough to a reserved word to avoid using it
                        > as a property name.

                        What's bad about using reserved words as property names?

                        In his book, Douglas mentions that it is *bad* that reserved words
                        cannot be used as object property names without quoting:

                        * Page 7, section "Names":

                        It is not permitted to name a variable or parameter with a reserved
                        word. Worse, it is not permitted to use a reserved word as the name
                        of an object property in an object literal or following a dot in a
                        refinement.

                        * Page 103, section "Reserved Words":

                        They cannot be used to name variables or parameters. When reserved
                        words are used as keys in object literals, they must be quoted. They
                        cannot be used with the dot notation, so it is sometimes necessary
                        to use the bracket notation instead:

                        var method; // ok
                        var class; // illegal
                        object = {box: value}; // ok
                        object = {case: value}; // illegal
                        object = {'case': value}; // ok
                        object.box = value; // ok
                        object.case = value; // illegal
                        object['case'] = value; //

                        > I also think it makes the code harder to read and understand, because
                        > whenever I read eval any where my first impression is that it is the
                        > eval function.

                        So what about "case" in the above example? Would you also avoid using
                        it?

                        The dot notation namespaces variable names, and to me that is not
                        confusing. To me reading `redisClient.eval` is no more confusing that
                        something like `redisClient.redisEval`. If one is confused by this, then
                        I propose avoiding `eval` at all, and instead name it `lave`. Surely,
                        `redisClient.lave` is less confusing... ;-)

                        I understand if Douglas doesn't want to make an exception on the basis
                        that this would make the parser too complicated. All the other
                        arguments, I don't understand.
                      Your message has been successfully submitted and would be delivered to recipients shortly.