Articulo de referencia

evaluación

En algunos lenguajes de programación , eval `evaluate`, abreviatura de ` evaluate` , es una función que evalúa una cadena como si fuera una expresión en el lenguaje y devuelve u...

En algunos lenguajes de programación , eval`evaluate`, abreviatura de ` evaluate` , 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 varias líneas de código como si se hubieran incluido en lugar de la línea que contiene `evaluate` eval. La entrada de `evaluate` 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 un tipo especial como code`evaluate` (como en Python). El análogo de una instrucción es `exec` , que ejecuta una cadena (o código en otro formato) como si fuera una instrucción; en algunos lenguajes, como Python, ambos están presentes, mientras que en otros lenguajes solo está uno de evalellos exec.

Riesgos de seguridad

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

sesión [ "autenticada" ] = Falso datos = obtener_datos () foo = evaluar ( datos )

Un atacante podría proporcionar al programa la cadena "session.update(authenticated=True)"como datos, lo que actualizaría el sessiondiccionario y establecería una clave autenticada como verdadera. Para solucionar esto, todos los datos que se utilicen evaldeben escaparse o el programa 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 programas que utilizan la evalfunción; a veces se utilizan intérpretes separados, aunque esto produce duplicación de código .

Lenguajes de programación

ECMAScript

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 ; alert ( eval ( 'foo + 2' ));

Ejemplo como ejecutor de sentencias:

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

Una de las aplicaciones de JavaScript evales el análisis de texto JSON , por ejemplo, como parte de un framework Ajax . Sin embargo, los navegadores modernos ofrecen JSON.parseuna alternativa más segura para esta tarea.

ActionScript

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 se limita a expresiones que representan "el nombre de una variable, propiedad, objeto o clip de película que se va a 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 ActionScript 3 Eval [ 2 ] y la API D.eval [ 3 ] fueron proyectos de desarrollo para crear equivalentes evalen ActionScript 3. Ambos han finalizado, ya que Adobe Flash Player ha llegado al final de su ciclo de vida .

Ceceo

Lisp fue el primer lenguaje en utilizar una evalfunción en 1958. De hecho, la definición de la evalfunción condujo a la primera implementación del intérprete del lenguaje. [ 4 ]eval Antes de que se definiera la función, las funciones de Lisp se compilaban manualmente a instrucciones en lenguaje ensambladoreval . Sin embargo, una vez compilada manualmente, la función se utilizaba como parte de un sencillo bucle de lectura-evaluación-impresión que constituyó la base del primer intérprete de Lisp.

Las versiones posteriores de la evalfunción Lisp también se han implementado como compiladores.

La evalfunción en Lisp espera que se evalúe una forma como su argumento. El valor resultante de la forma dada será el valor devuelto por la llamada a eval.

Este es un ejemplo de código Lisp:

; Una forma que llama a la función + con 1, 2 y 3 como argumentos. ; Devuelve 6. ( + 1 2 3 ) ; En Lisp, cualquier forma está destinada a ser evaluada, por lo tanto , ; se realizó la llamada a +. ; Podemos evitar que Lisp realice la evaluación ; de una forma anteponiéndole "'", por ejemplo: ( setq form1 ' ( + 1 2 3 )) ; Ahora form1 contiene una forma que puede ser utilizada por eval, por ejemplo: ( eval form1 ) ; eval evaluó (+ 1 2 3) y devolvió 6.

Lisp es conocido por su gran flexibilidad, al igual que la evalfunción. Por ejemplo, para evaluar el contenido de una cadena, primero habría que convertirla a un formato Lisp utilizando la read-from-stringfunción y, a continuación, pasar el formato resultante a eval:

( eval ( read-from-string "(format t \"¡Hola Mundo!!!~%\")" ) )

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

;; Define un formulario 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. ( environment-define user-initial-environment '+ - ) ;Valor: +;; Evalúe el formulario nuevamente. ;; Observe que el valor devuelto ha cambiado. ( eval form2 user-initial-environment ) ;Valor: 3

Perl

En Perl , esta 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 Perl) y permite omitir el punto y coma final.

Ejemplo como evaluador de expresiones:

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

Ejemplo como ejecutor de sentencias:

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

Perl también tiene evalbloques , que sirven como su mecanismo de manejo de excepciones (ver Sintaxis de manejo de excepciones#Perl ). Esto difiere del uso anterior de evalcon cadenas en que el código dentro de evallos 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 reportan como provenientes de una llamada a eval(), y las sentencias 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 sentencias completas, no solo expresiones; sin embargo, se puede obtener la forma de "expresión" evalcolocando la expresión en una sentencia return, lo que hace evalque devuelva el resultado de esa expresión.

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

Ejemplo usando echo:

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

Ejemplo de devolución de 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:

cargarcadena ( "print('¡Hola Mundo!')" )()

Ejemplo para realizar la evaluación en dos pasos:

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

Lua 5.2 desaconseja loadstringusar la loadfunción existente, que ha sido ampliada para aceptar cadenas. Además, permite proporcionar el entorno de la función directamente, ya que los entornos ahora son valores ascendentes .

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 "Hello World" de la pila y la muestra en la pantalla, para que tenga un tipo ejecutable, y luego se ejecuta.

El operador de PostScript runtiene una funcionalidad similar, pero en lugar de eso, 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 establecer un entorno restringido para la evaluación de la expresión.

La execinstrucción (o la execfunción en Python 3.x) ejecuta instrucciones:

execEjemplo (shell interactivo):

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

La forma más general de evaluar sentencias/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 execsentencia " ", una evalsentencia " " o una singlesentencia " ":

compileEjemplo (shell interactivo):

>>> x = 1 >>> y = 2 >>> eval ( compile ( "print 'x + y = ', x + y" , "compile-sample.py" , "single" )) x + y = 3

D

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

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

El ejemplo anterior se compilará exactamente en las mismas instrucciones de lenguaje ensamblador que si num++;se hubiera escrito directamente en lugar de mezclarse. El argumento de mixin no tiene por qué ser una cadena literal , sino expresiones arbitrarias que den como resultado un valor de cadena, incluidas las llamadas a funciones, que se pueden evaluar en tiempo de compilación.

Fusión fría

La función de ColdFusionevaluate permite a los usuarios evaluar una expresión de cadena en tiempo de ejecución.

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

Resulta especialmente útil cuando los usuarios necesitan seleccionar mediante programación la variable de la que desean leer los datos.

<cfset x = Evaluate ( "queryname. #columnname# [rownumber]" ) >

Rubí

El intérprete del lenguaje de programación Rubyeval ofrece una función similar a la de Python o Perl, y también permite especificar un ámbito o enlace .

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

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

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 \ Salidas "4"

BÁSICO

REALbasic

En REALbasic , existe una clase llamada RBScript que puede ejecutar código REALbasic en tiempo de ejecución. RBScript está muy aislado: solo dispone de las características esenciales del lenguaje, y los usuarios deben otorgarle acceso a las funcionalidades que deseen. Opcionalmente, pueden asignar un objeto a la propiedad `context`. Esto permite que el código en RBScript llame a funciones y utilice las propiedades del objeto de contexto. Sin embargo, aún se limita a comprender solo los tipos más básicos, por lo que si tienen una función que devuelve un `Dictionary` o `MySpiffyObject`, RBScript no podrá utilizarla. Los usuarios también pueden comunicarse con su RBScript mediante los eventos `Print` e `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 para Windows (escritas en lenguajes que no admiten Eval) mediante un control ActiveX llamado Control de script de Microsoft, cuyo método Eval puede ser llamado por el código de la aplicación. Para admitir la llamada a 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 elegido, antes de llamar a 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 donde el entorno de ejecución compila y ejecuta el código P. Su variante de Eval solo admite la evaluación de expresiones, las cuales pueden incluir funciones y objetos definidos por el usuario (pero no nombres de variables definidos por el usuario). Cabe destacar que el evaluador es diferente al de VBS, y la invocación de ciertas funciones definidas por el usuario puede funcionar de manera distinta en VBA que en el mismo código en VBScript.

Charla informal

Dado que las clases del compilador de Smalltalk forman parte de la biblioteca de clases estándar y suelen estar presentes en tiempo de ejecución, se pueden utilizar 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 el envío de mensajes (a objetos de clase), incluso son posibles los 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` eval, que ejecuta el código fuente proporcionado como argumento. Tcl representa todo el código fuente como cadenas, donde las llaves actúan como comillas, de modo que el argumento de `eval` evalpuede tener el mismo formato que cualquier otro código fuente.

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

bs

bs tiene una evalfunción que acepta un argumento de tipo cadena. Esta función evalúa expresiones y ejecuta sentencias. En este último caso, también puede utilizarse para el manejo de errores. Los siguientes ejemplos y texto provienen de la bspágina man tal como 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 su forma interna numérica. evalTambién se puede usar como una forma rudimentaria de indirección, como en el siguiente ejemplo (tenga en cuenta que, en bs, _(guion bajo) es el operador de concatenación):

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

lo cual incrementa la variable xyz.

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

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

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

Lo siguiente ejecuta una acción gotosobre la etiqueta L(si existe):

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

Intérpretes de línea de comandos

shells de Unix

El comando `eval` está presente en todos los intérpretes de comandos de Unix , incluido el original "sh" ( Bourne shell ). Concatena todos los argumentos con espacios, luego los vuelve a analizar y ejecuta el resultado como un comando. Manual de comandos generales de FreeBSDsh(1)  

PowerShell

En 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 PowerShell proporcionada como parámetro de comando en forma de cadena y muestra el resultado de dicha expresión. Generalmente, la salida del cmdlet es del mismo tipo que el resultado de la ejecución de la expresión. Sin embargo, si el resultado es una matriz vacía, muestra `<sup> $null-

Ejemplo como evaluador de expresiones:

PS > $foo = 2 PS > Invoke-Expression '$foo + 2'

Ejemplo como ejecutor de sentencias:

PS > $foo = 2 PS > Invoke-Expression '$foo += 2; $foo'

Microcódigo

En 1966, el Sistema de Programación Conversacional (CPS) de IBM introdujo una función microprogramada para realizar la "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 fue "sustancialmente más" cinco veces más rápida en comparación con un programa que interpretaba una instrucción de asignación . [ 8 ]EVAL

Teoría

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

( eval ' ( f x ) )

donde se debe evaluar la forma (fx), y

( aplicar f ( lista x ))

donde la función f debe ser llamada 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 simplemente tipado , 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 del original el 10 de octubre de 2006.
  2. Biblioteca de evaluación de ActionScript 3
  3. "La API de D.eval" . Archivado del 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)