【问题标题】:Is there ever a good reason to use eval()?是否有充分的理由使用 eval()?
【发布时间】:2009-12-01 15:19:10
【问题描述】:

在我看来,eval() 与 goto 一样受到轻视。 eval,我的意思是一个将字符串作为代码执行的函数,如 PHP、Python、JavaScript 等中所见。是否存在使用 eval() 是合理的情况(perl 除外)?如果没有,为什么有这么多语言实现它?

【问题讨论】:

  • 这个问题不能语言无关因为块eval在Perl中作为主要异常处理机制的特殊作用。因此,我向您提出,这个问题不可能有一个正确的答案:如果您正在使用 Perl 编程,那么使用 eval 是有充分理由的,而如果您正在使用 JavaScript 编程,则可能没有真正的充分理由。指定此问题适用的语言或将其设为 CW。
  • 没错,我不知道 eval() 在 perl 中是如何工作的。
  • 您是否在 Lisp 中包含 eval 函数?它在正常操作(读取-评估-打印循环)中是必不可少的,但根据我的经验,它几乎从未在此之外使用过。每次我受到诱惑时,看起来 Common Lisp 宏都是一个更好的主意。

标签: eval


【解决方案1】:

是 - 当没有其他方法可以以合理的清晰度和合理的代码行数完成给定任务时。

这消除了 99% 的使用 eval 的情况,在所有语言和环境中全面使用。

【讨论】:

    【解决方案2】:

    在动态生成代码的情况下,eval 通常是最方便的解决方案。即使在官方不支持 eval 的语言中,例如 Java,它们也支持在运行时对类进行反射和修改,这些都是相似的。 (参见 Stu Halloway 的 Component Development for the Java Platform 等书籍)

    【讨论】:

      【解决方案3】:

      一个合理的用途是,如果您有一种在另一种语言之上构建的解释性语言,但您仍希望提供某种“逃生舱”以允许人们返回由底层语言。一个例子是在 Lisp 中实现 Prolog,然后定义一个谓词,允许通过 EVAL 直接使用 Lisp 函数。

      【讨论】:

        【解决方案4】:

        对于快速破解,没问题,因为它是一个方便的快速退出。

        在生产代码中,将其视为最后的手段——即便如此,尝试其他方法——因为eval 难以控制,因此很危险。对于任何重要的事情,实现一种子语言。

        【讨论】:

          【解决方案5】:

          我在对网站进行渗透测试时使用过一次——我们编写了一个小型 php 脚本,它可以即时解密和执行来自未记录的 HTTP 数据源的加密签名的有效负载。这是迄今为止我见过的 eval() 最好的用法。

          (换句话说:不,我从未见过 eval 的好用处)

          【讨论】:

            【解决方案6】:

            临时想法:eval 非常适合实现穷人的表达式编译器,或类似的东西。它也是卫生宏的一种乏味、生锈的替代品。

            【讨论】:

              【解决方案7】:

              也许我使用 shperl 太多了,但我从未见过有人像对待 eval 那样轻视 goto

              所以我的回答是:'eval 适合你写perl 5sh'。 eval 块是 Perl 中主要的 try/catch 机制,没有它就很难编写安全代码。

              【讨论】:

              • 你是对的,也许它不像我想象的那样与语言无关。我的经验是使用 PHP 和 Python,普遍的共识似乎是,如果你想使用 eval,就不要。
              • 推论:不要将任何东西标记为“与语言无关”,除非您至少能熟悉十几种语言
              【解决方案8】:

              当您需要“生成”和执行代码时使用 Eval。生成是指从外部源(文件、网站、“代理”)包含以及在程序内部动态创建。

              除了外部模块和评估站点的明显示例之外,您想要生成代码的原因通常是在代码中动态引用对象和属性的名称。

              第一个例子,顺便说一句,当一个 HTML 页面被加载并且有一个脚本标签时,或者在 HTML 标签的事件处理程序属性中已经发生了——所以从一开始,Web 开发人员就在利用 EVAL,即使是浏览器发出调用。

              这间接地让我想到了第二个原因——访问对象的名称。在某些语言中,例如 java,内省的能力减少或消除了使用 java 的 eval 的需要。事实证明,由于 Javascript 中的对象是完全动态的,因此 Javascript 中的属性访问类似于其他语言中的自省,您可以在其中访问和引用动态创建的名称。此外,Javascript 有 'call' 和 'apply' 函数来动态调用带有参数的函数。

              最后,与执行代码相关,人们可能会使用 eval 来提高性能——而不是使用多级条件或属性访问来确定要运行的代码或要使用的对象,人们可能会创建一个最小的代码 sn-p可能必须执行数十万次,将其评估为一个函数,然后调用该函数。这可能适用于多种方法,例如,一旦确定了使用的特定参数。诚然,这是少数原因,因为 javascript 将函数视为第一类对象。

              【讨论】:

                【解决方案9】:

                在以正确的方式实施之前调试/测试一个想法。

                例如,您正在制作一个玩具计算器,并且您想先在 gui 上工作,所以您只需使用 eval 在后台执行“后端”工作。稍后,您回到后端,从头开始eval,并编写一个正确的表达式解析器。

                【讨论】:

                  【解决方案10】:

                  当创建/测试代码段时,eval 是完美的!

                  只需使用 textareas 和 eval 按钮构建一个基本的脚手架网页。 将代码放入文本区域,然后按 eval 按钮。它比在文本编辑器和浏览器之间来回切换要快

                  评估

                  edit code
                  press eval button
                  

                  切换方式

                  edit code
                  press save          extra step
                  switch to browser   extra step
                  press reload
                  

                  在对代码进行大量测试和调整时,额外的小步骤确实会加起来。另外,您可能会忘记在测试时避免造成混乱。

                  【讨论】:

                  • 或者按 f12 并使用控制台?
                  • 使用控制台编辑多行代码?好像不太实用。
                  猜你喜欢
                  • 2013-06-04
                  • 2010-10-18
                  • 2010-09-16
                  • 1970-01-01
                  • 2023-03-27
                  • 2018-02-11
                  • 2010-11-03
                  • 1970-01-01
                  • 2016-08-30
                  相关资源
                  最近更新 更多