evaluar

De Wikipedia, la enciclopedia libre
Saltar a navegación Saltar a buscar

En algunos lenguajes de programación , eval, abreviatura del inglés evaluar , 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 incluye el archivo eval. La entrada a evalno es necesariamente una cadena; puede ser una representación estructurada del código, como un árbol de sintaxis abstracta (como los formularios Lisp ), o de un 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 sentencia; en algunos lenguajes, como Python, ambos están presentes, mientras que en otros lenguajes solo uno de ellos evalo execestá presente.

Eval y apply son instancias de evaluadores metacirculares , intérpretes de un lenguaje que pueden invocarse dentro del lenguaje mismo. [ cita requerida ]

Riesgos de seguridad

El uso evalcon datos de una fuente no confiable puede presentar vulnerabilidades de seguridad. Por ejemplo, suponiendo que la get_data()función obtenga datos de Internet, este código de Python no es seguro:

sesión [ 'autenticado' ]  =  datos falsos 
= get_data () 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 remediar esto, se deben escapar todos los datos que se utilizarán eval, o se debe ejecutar sin acceso a funciones potencialmente dañinas.

Implementación

En lenguajes interpretados , evalcasi siempre se implementa con el mismo intérprete que el código normal. En lenguajes compilados , el mismo compilador que se usa para compilar programas se puede incrustar en programas que usan la evalfunción; A veces se utilizan intérpretes separados, aunque esto da como resultado la 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 declaraciones. Devuelve el resultado de la última expresión evaluada.

Ejemplo como evaluador de expresiones:

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

Ejemplo como ejecutor de sentencias:

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

Un uso de JavaScript evales analizar texto JSON , quizás como parte de un marco Ajax . Sin embargo, los navegadores modernos ofrecen JSON.parseuna alternativa más segura para esta tarea.

ActionScript

En ActionScript (lenguaje de programación de Flash), evalno se puede utilizar para evaluar expresiones arbitrarias. De acuerdo con 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 para recuperar. Este parámetro puede ser una cadena o una referencia directa a la instancia del objeto". [1]

ActionScript 3 no es compatible con eval.

La biblioteca de evaluación de ActionScript 3 [2] y la API de D.eval [3] son ​​proyectos de desarrollo en curso para crear equivalentes evalen ActionScript 3.

ceceo

Lisp fue el lenguaje original para hacer uso de 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 evalque se definiera la función, las funciones de Lisp se compilaban manualmente en sentencias de lenguaje ensamblador . Sin embargo, una vez que la evalfunción se compilaba manualmente, se usaba como parte de un ciclo simple de lectura, evaluación e impresión que formó la base del primer intérprete de Lisp.

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

La evalfunción en Lisp espera que un formulario sea evaluado y ejecutado como argumento. El valor de retorno del formulario dado será el valor de retorno de 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 una evaluación 
; de un formulario con el prefijo "'", por ejemplo: 
( setq  form1  ' ( +  1  2  3 )) 
; Ahora form1 contiene un formulario que puede ser usado por eval, for 
; ejemplo: 
( formulario eval1  ) ; eval evaluado (+ 1 2 3) y devuelto 6.

Lisp es bien conocido por ser muy flexible y también lo es la evalfunción. Por ejemplo, para evaluar el contenido de una cadena, la cadena primero tendría que convertirse en un formulario Lisp usando la read-from-stringfunción y luego el formulario resultante tendría que pasarse a eval:

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

Un punto importante de confusión es la pregunta, 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 según lo previsto. 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 evalfunción de Python, ver más abajo). Un ejemplo en el dialecto Scheme de Lisp (R 5 RS y posteriores):

;; Defina alguna forma simple como en el ejemplo anterior. 
( define form2  ' ( +  5  2 )) 
;Valor: form2

;; Evaluar la forma dentro del contexto inicial. 
;; Un contexto para la evaluación se denomina "entorno" en la jerga de Scheme. 
( eval form2  usuario-inicial-entorno ) 
; Valor: 7

;; Confundir el entorno inicial, por lo que + será 
;; un nombre para la función de resta. 
( entorno-define  usuario-inicial-entorno  '+  - ) 
; Valor: +

;; Evalúe el formulario nuevamente. 
;; Observe que el valor devuelto ha cambiado. 
( eval form2  usuario-inicial-entorno ) 
; Valor: 3

Perl

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

Ejemplo como evaluador de expresiones:

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

Ejemplo como ejecutor de sentencias:

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

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

PHP

En PHP , evalejecuta el código en una cadena casi exactamente como si se hubiera puesto 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 declaraciones 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, se puede obtener la forma de "expresión" evalcolocando 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 de lenguaje" en lugar de una función, [5] y, por lo tanto, no se puede usar en algunos contextos donde las funciones pueden ser, como las funciones de orden superior.

Ejemplo usando eco:

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

Ejemplo de devolver un valor:

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

Lúa

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

Ejemplo como evaluador de expresiones:

cadena de carga ( "imprimir ('¡Hola mundo!')" )()

Ejemplo para hacer 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 queda en desuso loadstringa favor de la loadfunción existente, que se ha aumentado para aceptar cadenas. Además, permite proporcionar el entorno de la función directamente, ya que los entornos ahora son upvalues .

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

post script

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

 ((Hola mundo) =)  ejecutivo cvx 

convierte la expresión PostScript

 (Hola mundo)  =

que saca la cadena "Hello World" de la pila y la muestra en la pantalla, para tener un tipo ejecutable, luego se ejecuta.

El operador de PostScript runtiene una funcionalidad similar, pero en su lugar, el intérprete interpreta las expresiones de 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 
>>> valor ( 'x + 1' ) 
2 
>>> valor ( '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 sentencias/expresiones es usar objetos de código. 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 " mixin" la cadena se compila estáticamente como código normal y debe conocerse en tiempo de compilación. Por ejemplo:

 estándar de importación estudio _

vacío  principal ()  { 
    int  num  =  0 ; 
    mezclando ( "num++;" ); 
    escribirln ( num );   // Imprime 1. 
}

El ejemplo anterior compilará exactamente las mismas instrucciones en lenguaje ensamblador que si " num++;" se hubiera escrito directamente en lugar de mezclado. El argumento para mezclar no necesita ser una cadena literal, sino expresiones arbitrarias que dan como resultado un valor de cadena, incluida la función llamadas, que se pueden evaluar en tiempo de compilación.

ColdFusion

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 particularmente útil cuando necesita elegir programáticamente la variable que desea leer.

<cfset  x  =  Evaluate ( "nombre de consulta. #nombre de columna# [número de fila]" ) >

rubí

El intérprete del lenguaje de programación Rubyeval ofrece una funció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 usar 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)

# evaluando dentro de un contexto 
def  get_binding ( a ) 
  binding 
end 
eval ( 'a+1' , get_binding ( 3 ))  # (evalúa a 4, porque 'a' en el contexto de get_binding es 3)
 prueba de clase ;  Prueba final 
. class_eval ( "def hola; devuelve 'hola';fin" ) # agrega un método 'hola' a esta clase Prueba . nuevo _ hola # se evalúa como "hola" 
                    

cuarto

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"

FRED

Framework FRED es un lenguaje interactivo en el que Eval evalúa automáticamente todo el código. Los parámetros de cadena en los ejemplos a continuación se ejecutarán de la misma manera que si se escribieran y ejecutaran en una fórmula o cuando se seleccionaran y ejecutaran. El Ampersand & es el operador de concatenación de cadenas. Eval concatena, resuelve y evalúa recursivamente su parámetro. FRED también tiene una función interna llamada @valueque evalúa una cadena de parámetros. @valueEl segundo parámetro numérico opcional de indica el tipo de entrada y los formatos para tipos especiales como fechas, horas. etc. y determina el formato del valor devuelto.

Por razones de seguridad, el ámbito de referencia de @value es relativo global, por lo que las variables locales creadas con @local son invisibles para @value. Solo se pueden "ver" por código en la misma área de fórmula. (vea el ejemplo a continuación), del mismo modo, las variables locales creadas en el alcance de @value solo pueden ser vistas por @value y son invisibles para el código en la misma fórmula o cualquier otro código. (ver comentario (1*) a continuación)

Ejemplos de código de FRED:

@value("5 + 4 + 1") # Devuelve el valor numérico 10
@value("2" & "3") # Devuelve el valor numérico 23
@value("2" & " + 3") # Devuelve el valor numérico 5
@value("2" & "+" & "3") # Devuelve el valor numérico 5
@value("2 + 3") # Devuelve el valor numérico 5

mi_var := 3,
@value("2 + my_var") # Devuelve el valor numérico 5

mi_var := -3,
@value("2 + @abs(my_var)") # Devuelve el valor numérico 5

Por razones de seguridad, esto devolverá un error ya que el alcance de @value es global y @local es invisible para las referencias globales y solo puede ser "visto" por el código en su propia fórmula.  
@local(a,b),
un := 1,
segundo := 2,
@value("a + b") # devuelve un valor de error (1*)

pero si a y b son marcos @value que pueden hacer referencia a marcos variables tanto globales como relativos, @value puede "verlos"
un := 1,
segundo := 2,
@value("a + b") # Devuelve el valor numérico 3

Esta línea de código devolverá 3 porque las variables locales se crean y se ven en el alcance de @value
@value("@local(a,b),a:=1,b:=2,a+b") # Devuelve el valor numérico 3

Pero las siguientes dos líneas de código devolverán un error de referencia indefinido porque a y b se crean en el ámbito @value local y son invisibles para el resto del código en la fórmula, de hecho para cualquier código en cualquier lugar excepto en este ámbito @value.
@valor("@local(a,b),a:=1,b:=2),
a+b # Devuelve un error de referencia indefinido

@value("{12/12/2012}",16) # Devuelve la cadena "12 de diciembre de 2012"

@value("@fileload(@inputline(""Ingrese la letra de la unidad"",""" & @item1 & """) & " & """:\myfile.txt"")") # donde @item1 es parámetro recibido "c",

will ejecuta las partes de la cadena, construye la cadena a continuación y la ejecuta como un programa que comienza con @inputline solicitando la entrada del usuario, sugiriendo "C". Si el usuario ingresa C, @fileload se ejecuta con la cadena "c:\myfile.txt" como su parámetro:

@fileload(@inputline("Ingrese la letra de la unidad", "c") & ":\myfile.txt") # carga myfile.txt en el escritorio

BÁSICO

REALbasic

En REALbasic , hay una clase llamada RBScript que puede ejecutar código REALbasic en tiempo de ejecución. RBScript está muy aislado: solo están ahí las funciones más básicas del lenguaje y debe permitirle el acceso a las cosas que desea que tenga. Opcionalmente, puede 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 se limita a comprender solo los tipos más básicos, por lo que si tiene una función que devuelve un Diccionario o MySpiffyObject, RBScript no podrá usarla. También puede comunicarse con su RBScript a través de los eventos de impresión y entrada.

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 declaraciones separadas por dos puntos, que pueden cambiar el estado global.

Tanto VBScript como JScript evalestán disponibles para los desarrolladores de aplicaciones de Windows compiladas (escritas en lenguajes que no admiten Eval) a través de un control ActiveX llamado Microsoft Script Control, cuyo método Eval puede ser llamado por el código de la aplicación. Para admitir la llamada 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 definidas en el idioma de su elección, 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 tiempo de ejecución compila y ejecuta p-code . Su versión 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 pequeña

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.

Evaluación del compilador  : '1 + 2'

Debido a que las definiciones de clase y método también se implementan mediante envíos de mensajes (a objetos de clase), incluso los cambios de código son posibles:

Evaluación del compilador  : 'Subclase de objeto: #Foo'

Tcl

El lenguaje de programación Tcleval tiene un comando llamado , que ejecuta el código fuente provisto 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.

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

 

bs

bs tiene una evalfunción que toma un argumento de cadena. La función es tanto un evaluador de expresiones como un ejecutor de declaraciones. En la última función, también se puede utilizar para el manejo de errores. Los siguientes ejemplos y texto son de la bs página del manual tal como aparece en el Manual del programador de UNIX System V versión 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 interno numérico. También evalse puede usar como una forma cruda de direccionamiento indirecto, como se muestra a continuación (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 un archivo llamado "XXX" (en lugar de detener el programa del usuario).

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

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

Intérpretes de línea de comandos

Conchas Unix

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

Windows PowerShell

En Windows PowerShell , el Invoke-ExpressionCmdlet cumple el mismo propósito 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 elemento único. Al igual que JavaScript, Windows PowerShell permite omitir el punto y coma final.

Ejemplo como evaluador de expresiones:

PS > $foo  =  2 
PS > invocar expresión  '$foo + 2'

Ejemplo como ejecutor de sentencias:

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

Microcódigo

En 1966 , el Sistema de programación conversacional de IBM (CPS) introdujo una función microprogramada para realizar una "evaluación interpretativa de expresiones que están escritas en una notación de cadena polaca modificada " en un IBM System / 360 Model 50 . [7] Microcodificar esta función fue "sustancialmente más" que cinco veces más rápido en comparación con un programa que interpretó una declaración de asignación . [8]EVAL

Teoría

En informática teórica , se suele hacer una cuidadosa distinción 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 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

( evaluar  ' ( f  x )  )

donde se va a evaluar la forma (fx), y

( aplicar  f  ( enumerar  x ))

donde se 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 evaluar Lisp, descrito en SICP . [9]

En la 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 las funciones tomadas como morfismos, y el producto cartesiano tomado como producto , forma una categoría cerrada cartesiana . Aquí, eval (o, propiamente hablando, apply ) junto con su adjunto derecho , curry , forman el cálculo lambda simplemente tipificado , que puede interpretarse como los morfismos de las categorías cartesianas cerradas.

Referencias

  1. ^ "Flash 8 LiveDocs" . 2006-10-10. Archivado desde el original el 10 de octubre de 2006.
  2. ^ Biblioteca de evaluación de 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: evaluación - Manual" . PHP.net . _ Consultado el 10 de septiembre de 2015 .
  6. ^ "Comandos y utilidades del volumen 1" . Manual del programador de UNIX (PDF) . AT&T. 1986. pág. 41.
  7. ^ Allen-Babcock. "Proyecto de 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 (SICP Sección 4.1)

Enlaces externos