stringtranslate.com

evaluar

En algunos lenguajes de programación , eval, abreviatura del inglés evaluating, es una función que evalúa una cadena como si fuera una expresión en el lenguaje y devuelve un resultado ; en otros, ejecuta múltiples líneas de código como si se hubieran incluido en lugar de la línea que incluye el eval. La entrada a evalno es necesariamente una cadena; puede ser una representación estructurada de código, como un árbol de sintaxis abstracta (como las formas de Lisp ), o de tipo especial como code(como en Python). El análogo para una declaración es exec , que ejecuta una cadena (o código en otro formato) como si fuera una declaración; en algunos lenguajes, como Python, ambos están presentes, mientras que en otros lenguajes solo está uno de ellos evalo exec.

Riesgos de seguridad

El uso evalde datos de una fuente no confiable puede generar vulnerabilidades de seguridad. Por ejemplo, suponiendo que la get_data()función obtiene datos de Internet, este código Python es inseguro:

sesión [ 'autenticado' ]  =  Falso datos  =  obtener_datos () foo  =  eval ( datos )

Un atacante podría proporcionar al programa la cadena "session.update(authenticated=True)"como datos, lo que actualizaría el sessiondiccionario para establecer una clave autenticada como Verdadera. Para solucionar esto, todos los datos que se utilizarán con evaldeben ser escapados, o debe ejecutarse sin acceso a funciones potencialmente dañinas.

Implementación

En los lenguajes interpretados , evalcasi siempre se implementa con el mismo intérprete que el código normal. En los lenguajes compilados , el mismo compilador utilizado para compilar programas puede estar integrado en los programas que utilizan la evalfunción; a veces se utilizan intérpretes independientes, aunque esto da como resultado la duplicación del código .

Lenguajes de programación

Script ECMA

JavaScript

En JavaScript , evales una especie de híbrido entre un evaluador de expresiones y un ejecutor de sentencias. Devuelve el resultado de la última expresión evaluada.

Ejemplo como evaluador de expresiones:

foo = 2 ; alerta ( eval ( 'foo + 2' ));  

Ejemplo como ejecutor de sentencia:

foo = 2 ; eval ( 'foo = foo + 2; alerta (foo);' );  

Uno de los usos de JavaScript evales analizar texto JSON , tal vez como parte de un marco AjaxJSON.parse . Sin embargo, los navegadores modernos ofrecen una alternativa más segura para esta tarea.

Script de acción

En ActionScript (el lenguaje de programación de Flash), evalno se puede utilizar para evaluar expresiones arbitrarias. Según la documentación de Flash 8, su uso está limitado a expresiones que representan "el nombre de una variable, propiedad, objeto o clip de película que se desea recuperar. Este parámetro puede ser una cadena o una referencia directa a la instancia del objeto". [1]

ActionScript 3 no admite eval.

La biblioteca de evaluación ActionScript 3 [2] y la API D.eval [3] eran proyectos de desarrollo para crear equivalentes evalen ActionScript 3. Ambos finalizaron, ya que Adobe Flash Player llegó al final de su vida útil .

Ceceo

Lisp fue el lenguaje original que utilizó una evalfunción en 1958. De hecho, la definición de la evalfunción condujo a la primera implementación del intérprete de lenguaje. [4] Antes de que evalse definiera la función, las funciones de Lisp se compilaban manualmente en instrucciones de lenguaje ensamblador . Sin embargo, una vez que la evalfunción se había compilado manualmente, se utilizaba como parte de un simple bucle de lectura-evaluación-impresión que formó la base del primer intérprete de Lisp.

Las versiones posteriores de la función Lisp evaltambién se han implementado como compiladores.

La evalfunción en Lisp espera que se evalúe un formulario como su argumento. El valor resultante del formulario dado será el valor devuelto de la llamada a eval.

Este es un ejemplo de código Lisp:

; Un formulario que llama a la función + con 1,2 y 3 como argumentos. ; Devuelve 6. ( + 1 2 3 ) ; En Lisp, cualquier formulario debe evaluarse, por lo tanto , ; se realizó la llamada a +. ; Podemos evitar que Lisp realice la evaluación de un formulario anteponiéndole el prefijo "'", por ejemplo: ( setq form1 ' ( + 1 2 3 )) ; Ahora form1 contiene un formulario que puede ser utilizado por eval, por ; ejemplo: ( eval form1 ) ; eval evaluó (+ 1 2 3) y devolvió 6.         

Se sabe que Lisp es muy flexible, al igual que la evalfunción. Por ejemplo, para evaluar el contenido de una cadena, primero habría que convertir la cadena a un formato Lisp mediante la read-from-stringfunción y luego habría que pasar el formato resultante a eval:

( eval ( lectura-de-cadena "(formato t \"¡Hola mundo!!!~%\")" ))  

Un punto de confusión importante es la cuestión de en qué contexto se evaluarán los símbolos del formulario. En el ejemplo anterior, form1contiene el símbolo +. La evaluación de este símbolo debe generar la función para la suma para que el ejemplo funcione como se pretende. Por lo tanto, algunos dialectos de Lisp permiten un parámetro adicional para evalespecificar el contexto de evaluación (similar a los argumentos opcionales para la función de Python eval; consulte a continuación). Un ejemplo en el dialecto Scheme de Lisp (R 5 RS y posteriores):

;; Defina una forma simple como en el ejemplo anterior. ( define form2 ' ( + 5 2 )) ;Valor: form2    ;; Evalúa el formulario dentro del contexto inicial. ;; Un contexto para la evaluación se denomina "entorno" en la jerga de Scheme. ( eval form2 user-initial-environment ) ;Valor: 7  ;; Confundir el entorno inicial, de modo que + sea ;; un nombre para la función de resta. ( entorno-definir entorno-inicial-usuario '+ - ) ;Valor: +   ;; Evalúe el formulario nuevamente. ;; Observe que el valor devuelto ha cambiado. ( eval form2 user-initial-environment ) ;Valor: 3  

Perl

En Perl , la evalfunción es una especie de híbrido entre un evaluador de expresiones y un ejecutor de sentencias. Devuelve el resultado de la última expresión evaluada (todas las sentencias son expresiones en la programación de Perl) y permite omitir el punto y coma final.

Ejemplo como evaluador de expresiones:

$foo = 2 ; imprimir eval ( '$foo + 2' ), "\n" ;    

Ejemplo como ejecutor de sentencia:

$foo = 2 ; eval ( '$foo += 2; imprimir "$foo\n";' );  

Perl también tiene eval bloques , que sirven como mecanismo de manejo de excepciones (consulte Sintaxis de manejo de excepciones#Perl ). Esto difiere del uso anterior de evalwith strings en que el código dentro evalde bloques se interpreta en tiempo de compilación en lugar de tiempo de ejecución, por lo que no es el significado de evalutilizado en este artículo.

PHP

En PHP , evalejecuta el código en una cadena casi exactamente como si se hubiera colocado en el archivo en lugar de la llamada a eval(). La única excepción es que los errores se informan como provenientes de una llamada a eval(), y las instrucciones de retorno se convierten en el resultado de la función.

A diferencia de algunos lenguajes, el argumento evaldebe ser una cadena de una o más declaraciones completas, no solo expresiones; sin embargo, uno puede obtener la forma de "expresión" de evalponiendo la expresión en una declaración de retorno, lo que hace evalque se devuelva el resultado de esa expresión.

A diferencia de algunos lenguajes, PHP evales una "construcción del lenguaje" en lugar de una función, [5] y por lo tanto no se puede utilizar en algunos contextos en los que sí se pueden utilizar funciones, como las funciones de orden superior.

Ejemplo usando echo:

<?php $foo  =  "Hola, mundo! \n " ; eval ( 'echo "$foo";' ); ?>

Ejemplo que devuelve un valor:

<?php $foo  =  "Adiós, mundo! \n " ;  //no funciona en PHP5 echo  eval ( 'return $foo;' ); ?>

Lua

En Lua 5.1, loadstringcompila el código Lua en una función anónima.

Ejemplo como evaluador de expresiones:

loadstring ( "print('¡Hola mundo!')" )()

Ejemplo para realizar la evaluación en dos pasos:

a  =  1 f  =  loadstring ( "return a + 1" )  - compila la expresión en una función anónima print ( f ())  - ejecuta (e imprime el resultado '2')

Lua 5.2 se desactualiza loadstringen favor de la loadfunción existente, que se ha ampliado para aceptar cadenas. Además, permite proporcionar el entorno de la función directamente, ya que los entornos ahora son upvalues ​​.

cargar ( "print('Hola ' .. a)" ,  "" ,  "t" ,  {  a  =  "¡Mundo!" ,  print  =  print  })()

Posdata

El operador de PostScriptexec toma un operando: si es un literal simple, lo vuelve a colocar en la pila. Sin embargo, si se toma una cadena que contiene una expresión PostScript, se puede convertir la cadena en un ejecutable que luego puede ser ejecutado por el intérprete, por ejemplo:

 ((Hola mundo) =) cvx exec  

convierte la expresión PostScript

 (Hola mundo) = 

que extrae la cadena "Hola mundo" de la pila y la muestra en la pantalla, para que tenga un tipo ejecutable, luego se ejecuta.

El operador de PostScript runes similar en funcionalidad pero, en cambio, el intérprete interpreta las expresiones PostScript en un archivo.

(archivo.ps) ejecutar 

Pitón

En Python , la evalfunción en su forma más simple evalúa una sola expresión.

evalEjemplo (shell interactivo):

>>> x  =  1 >>> eval ( 'x + 1' ) 2 >>> eval ( 'x' ) 1

La evalfunción toma dos argumentos opcionales, globaly locals, que permiten al programador configurar un entorno restringido para la evaluación de la expresión.

La execdeclaración (o la execfunción en Python 3.x) ejecuta declaraciones:

execEjemplo (shell interactivo):

>>> x  =  1 >>> y  =  1 >>> exec  "x += 1; y -= 1" >>> x 2 >>> y 0

La forma más general de evaluar declaraciones/expresiones es mediante objetos de código. Estos se pueden crear invocando la compile()función y diciéndole qué tipo de entrada tiene que compilar: una execdeclaración " ", una evaldeclaración " " o una singledeclaración " ":

compileEjemplo (shell interactivo):

>>> x  =  1 >>> y  =  2 >>> eval  ( compilar  ( "imprimir 'x + y = ', x + y" ,  "compilar-muestra.py" ,  "single" )) x + y = 3

D

D es un lenguaje compilado estáticamente y, por lo tanto, no incluye una evaldeclaración " " en el sentido tradicional, pero sí incluye la mixindeclaración relacionada " ". La diferencia es que, donde " eval" interpreta una cadena como código en tiempo de ejecución, con un " mixin" la cadena se compila estáticamente como código ordinario y debe conocerse en tiempo de compilación. Por ejemplo:

importar std . stdio ; void main () { int num = 0 ; mixin ( "num++;" ); writeln ( num ); // Imprime 1. }         

El ejemplo anterior se compilará exactamente con las mismas instrucciones en lenguaje ensamblador como si " num++;" se hubiera escrito directamente en lugar de mezclarlo. El argumento de mixin no necesita ser un literal de cadena, sino expresiones arbitrarias que resulten en un valor de cadena, incluidas las llamadas de función, que se pueden evaluar en tiempo de compilación.

Fusión fría

La función de ColdFusionevaluate le permite evaluar una expresión de cadena en tiempo de ejecución.

<cfset  x  =  "int(1+1)" > <cfset  y  =  Evaluar ( x ) >

Es especialmente útil cuando necesitas elegir programáticamente la variable que quieres leer.

<cfset  x  =  Evaluate ( "nombreconsulta. #nombrecolumna# [númerofila]" ) >

Rubí

El intérprete del lenguaje de programación Ruby ofrece una evalfunción similar a Python o Perl, y también permite especificar un alcance o enlace .

Además de especificar el enlace de una función, evaltambién se puede utilizar para evaluar una expresión dentro de un enlace de definición de clase específico o un enlace de instancia de objeto, lo que permite ampliar las clases con nuevos métodos especificados en cadenas.

a = 1 eval ( 'a + 1' ) # (evalúa a 2)   # evaluar dentro de un contexto def get_binding ( a ) binding end eval ( 'a+1' , get_binding ( 3 )) # (se evalúa como 4, porque 'a' en el contexto de get_binding es 3)   
clase Test ; fin Test . class_eval ( "def hola; return 'hola'; fin" ) # agrega un método 'hola' a esta clase Test . new . hola # evalúa a "hola"    

Adelante

La mayoría de las implementaciones estándar de Forth tienen dos variantes de eval: EVALUATEy INTERPRET.

Ejemplo de código Win32FORTH:

 S" 2 2 + . " EVALUAR \ Salida "4"   

BÁSICO

REALbásico

En REALbasic , hay una clase llamada RBScript que puede ejecutar código REALbasic en tiempo de ejecución. RBScript está muy restringido: solo están las características más básicas del lenguaje y debes permitirle el acceso a las cosas que quieres que tenga. Opcionalmente, puedes asignar un objeto a la propiedad de contexto. Esto permite que el código en RBScript llame a funciones y use propiedades del objeto de contexto. Sin embargo, todavía está limitado a comprender solo los tipos más básicos, por lo que si tienes una función que devuelve un Dictionary o MySpiffyObject, RBScript no podrá usarlo. También puedes comunicarte con tu RBScript a través de los eventos Print y Input.

VBScript

VBScript de Microsoft, que es un lenguaje interpretado, tiene dos construcciones. Evales un evaluador de funciones que puede incluir llamadas a funciones definidas por el usuario. (Estas funciones pueden tener efectos secundarios, como cambiar los valores de las variables globales). Executeejecuta una o más instrucciones separadas por dos puntos, que pueden cambiar el estado global.

Tanto VBScript como JScript evalestán disponibles para los desarrolladores de aplicaciones compiladas de Windows (escritas en lenguajes que no admiten Eval) a través de un control ActiveX llamado Microsoft Script Control, cuyo método Eval puede ser invocado por el código de la aplicación. Para admitir la invocación de funciones definidas por el usuario, primero se debe inicializar el control con el método AddCode, que carga una cadena (o un recurso de cadena) que contiene una biblioteca de funciones definidas por el usuario en el lenguaje de la elección, antes de invocar Eval.

Visual Basic para aplicaciones

Visual Basic para Aplicaciones (VBA), el lenguaje de programación de Microsoft Office, es un lenguaje de máquina virtual en el que el entorno de ejecución compila y ejecuta código p . Su variante de Eval solo admite la evaluación de expresiones, donde la expresión puede incluir funciones y objetos definidos por el usuario (pero no nombres de variables definidos por el usuario). Cabe destacar que el evaluador es diferente de VBS y la invocación de ciertas funciones definidas por el usuario puede funcionar de manera diferente en VBA que el código idéntico en VBScript.

Charla informal

Como las clases del compilador de Smalltalk son parte de la biblioteca de clases estándar y generalmente están presentes en tiempo de ejecución, se pueden usar para evaluar una cadena de código.

El compilador  evalúa: '1 + 2'

Dado que las definiciones de clases y métodos también se implementan mediante envíos de mensajes (a objetos de clase), incluso son posibles cambios en el código:

El compilador  evalúa: 'Subclase de objeto: #Foo'

Tcl

El lenguaje de programación Tcl tiene un comando llamado eval, que ejecuta el código fuente proporcionado como argumento. Tcl representa todo el código fuente como cadenas, con llaves que actúan como comillas, de modo que el argumento to evalpuede tener el mismo formato que cualquier otro código fuente.

establecer  foo { mientras {[ incr i ] < 10 } { pone "$i al cuadrado es [expr $i*$i]" } } eval $foo      

bs

bs tiene una evalfunción que toma como argumento una cadena. La función es a la vez un evaluador de expresiones y un ejecutor de sentencias. En este último rol, también se puede utilizar para el manejo de errores. Los siguientes ejemplos y textos son de la bs página del manual que aparece en el Manual del programador de UNIX System V Release 3.2. [6]

El argumento de cadena se evalúa como una bsexpresión. La función es útil para convertir cadenas numéricas a formato numérico interno. evalTambién se puede utilizar como una forma básica de indirección, como en el siguiente ejemplo (tenga en cuenta que, en bs, _(guión bajo) es el operador de concatenación):

nombre = "xyz"
eval ( "++" _ nombre )    

que incrementa la variable xyz.

Además, evalprecedido por el operador de interrogación, ?, permite al usuario controlar bslas condiciones de error. Por ejemplo:

?eval ( "abrir(\"X\", \"XXX\", \"r\")" )

devuelve el valor cero si no hay ningún archivo llamado "XXX" (en lugar de detener el programa del usuario).

Lo siguiente ejecuta gotoa la etiqueta L(si existe):

etiqueta = "L" si ! ( ?eval ( "goto " _ etiqueta )) puterr = "sin etiqueta"        

Intérpretes de línea de comandos

Conchas de Unix

El comando eval está presente en todos los shells de Unix , incluido el "sh" original ( Bourne shell ). Concatena todos los argumentos con espacios, luego vuelve a analizarlos y ejecuta el resultado como un comando. sh(1) –  Manual de comandos generales de FreeBSD

Windows PowerShell

En Windows PowerShell , el Invoke-Expressioncmdlet cumple la misma función que la función eval en lenguajes de programación como JavaScript, PHP y Python. El cmdlet ejecuta cualquier expresión de Windows PowerShell que se proporcione como parámetro de comando en forma de cadena y genera el resultado de la expresión especificada. Por lo general, la salida del cmdlet es del mismo tipo que el resultado de ejecutar la expresión. Sin embargo, si el resultado es una matriz vacía, genera $null. En caso de que el resultado sea una matriz de un solo elemento, genera ese único elemento. De manera similar a JavaScript, Windows PowerShell permite omitir el punto y coma final.

Ejemplo como evaluador de expresiones:

PS > $foo  =  2 PS > expresión-invocación  '$foo + 2'

Ejemplo como ejecutor de sentencia:

PS > $foo  =  2 PS > expresión-invocación  '$foo += 2; $foo'

Microcódigo

En 1966, IBM Conversational Programming System (CPS) introdujo una función microprogramadaEVAL para realizar una "evaluación interpretativa de expresiones escritas en una notación de cadena polaca modificada " en un IBM System/360 Modelo 50. [ 7] La ​​microcodificación de esta función era "sustancialmente" más de cinco veces más rápida en comparación con un programa que interpretaba una declaración de asignación . [8]

Teoría

En la informática teórica , se suele hacer una distinción cuidadosa entre eval y apply . Se entiende por eval el paso de convertir una cadena entre comillas en una función invocable y sus argumentos, mientras que apply es la llamada real de la función con un conjunto dado de argumentos. La distinción es particularmente notable en lenguajes funcionales y lenguajes basados ​​en cálculo lambda , como LISP y Scheme . Así, por ejemplo, en Scheme, la distinción es entre

( eval ' ( fx ) )   

donde se debe evaluar la forma (fx), y

( aplica f ( lista x ))   

donde se debe llamar a la función f con el argumento x .

Eval y apply son los dos componentes interdependientes del ciclo eval-apply , que es la esencia de la evaluación de Lisp, descrita en SICP . [9]

En teoría de categorías , el morfismo eval se utiliza para definir la categoría monoidal cerrada . Así, por ejemplo, la categoría de conjuntos , con funciones tomadas como morfismos y el producto cartesiano tomado como producto , forma una categoría cartesiana cerrada . Aquí, eval (o, propiamente hablando, apply ) junto con su adjunto derecho , currying , forman el cálculo lambda de tipos simples , que puede interpretarse como los morfismos de categorías cartesianas cerradas.

Véase también

Referencias

  1. ^ "Flash 8 LiveDocs". 10 de octubre de 2006. Archivado desde el original el 10 de octubre de 2006.
  2. ^ Biblioteca de evaluación ActionScript 3
  3. ^ "La API de D.eval". Archivado desde el original el 14 de marzo de 2013.
  4. ^ John McCarthy, "Historia de Lisp - La implementación de Lisp"
  5. ^ "PHP: eval - Manual". PHP .net . Consultado el 10 de septiembre de 2015 .
  6. ^ "Volumen 1 Comandos y utilidades". Manual del programador de UNIX (PDF) . AT&T. 1986. pág. 41.
  7. ^ Allen-Babcock. "Borrador del microprograma EVAL" (PDF) . Bitsavers.org . Consultado el 17 de enero de 2016 .
  8. ^ Rochester, Nathaniel. "Informe de progreso del sistema de programación conversacional" (PDF) . Bitsavers.org . Consultado el 17 de enero de 2016 .
  9. ^ El evaluador metacircular (Sección 4.1 del SICP)

Enlaces externos