2009-05-15 13 views
10

¿Por qué el compilador de Erlang no detecta las funciones no definidas en tiempo de compilación?¿Por qué compila erlang: foo()?

Si escribo test.erl:

-module(test). 
-export([start/0]). 

start() -> 
     erlang:foo(). 

Se compila bien.

Eshell V5.6.5 (abort with ^G) 
1> c(test). 
{ok,test} 
2> 

Pero se bloquea el tiempo de ejecución.

2> test:start(). 
** exception error: undefined function erlang:foo/0 

¿Por qué no es la cuestión compilador de un error o una advertencia sobre esto durante la compilación? Debe saber sobre las funciones exportadas, ¿no es así?

Respuesta

16

Erlang es un lenguaje dinámico. Sin embargo, es una buena práctica hacer la verificación de tipos y el análisis estático post-compilación.

La herramienta Dialyzer se utiliza para verificar este tipo de condición de error.

El motivo por el que el compilador no lo conoce en tiempo de compilación es porque las funciones se pueden buscar y cargar dinámicamente desde la ruta del código en tiempo de ejecución (y también desde un nodo remoto). El dializador comprobará el código contra la ruta del código en el momento en que se ejecuta.

La capacidad de cargar código desde un nodo remoto significa que los 'sistemas' básicos pueden instalarse en un dispositivo y luego el dispositivo puede arrancarse desde la red.

También debe recordar otra de las características de Erlang que se puede generar llamadas de función on the fly usando construcciones como:

erlang:apply(ModuleName, FunctionName, ArgList) 

por lo que en ese caso, simplemente no es posible saber si la función existe en tiempo de compilación o no .

Y aunque el módulo y la función pueden existir ahora en tiempo de compilación, puede intercambiar módulos en caliente y descargar el código, por lo que puede no estar allí en tiempo de ejecución.

+1

No solo la ruta del código sino otros nodos en un clúster de Erlang.El código no tiene que ser local para ser cargado en una VM de Erlang y ejecutado. –

+1

Realmente no había pensado en eso. Una mirada rápida al libro de cocina de Erlang muestra cómo hacerlo. http://www.trapexit.org/Remote_Code_Load –

+0

Además, puede reemplazar o descargar el módulo en tiempo de ejecución, por lo que incluso si el compilador lo comprobara ahora, aún podría fallar más tarde. – archaelus

0

Creo que esta es una pregunta de implementación ya que los desarrolladores de Erlang decidieron vincular el tiempo de ejecución en lugar de vincular el tiempo de compilación. Parte del motivo puede tener algo que ver con el control de versiones y/o la carga de códigos dinámicos.

0

Puede usar la aplicación xref para verificar el uso de funciones obsoletas, indefinidas y no utilizadas (¡y más!).

compilar el módulo con debug_info:

Eshell V6.2 (abort with ^G) 
1> c(test, debug_info). 
{ok,test} 

Comprobar el módulo con xref:m/1:

2> xref:m(test). 
[{deprecated,[]}, 
{undefined,[{{test,start,0},{erlang,foo,0}}]}, 
{unused,[]}] 

Es posible que desee ver más acerca xref aquí:

Erlang -- Xref - The Cross Reference Tool (Tools User's Guide)

Erlang -- xref (Tools Reference Manual)

Cuestiones relacionadas