2008-10-30 19 views
9

He oído que hay algunas cosas que uno no puede hacer como programador de computadoras, pero no sé cuáles son. Una cosa que se me ocurrió recientemente fue: ¿no sería bueno tener una clase que pudiera hacer una copia de la fuente del programa que ejecuta, modificar ese programa y agregar un método a la clase que es, y luego ejecutarlo la copia del programa y terminar por sí mismo. ¿Es posible que el código escriba código?¿Es posible escribir código para escribir código?

Respuesta

13

Empieza por mirar quines, luego en Macro-Ensambladores y luego lex & yacc, y flex & bison. Luego considere self-modifying code.

Aquí está un quine (formato, utilice la salida como la nueva entrada):

#include<stdio.h> 

main() 
{ 
    char *a = "main(){char *a = %c%s%c; int b = '%c'; printf(a,b,a,b,b);}"; 
    int b = '"'; 
    printf(a,b,a,b,b); 
} 

Ahora bien, si usted está buscando cosas programadores no pueden hacer buscar el opuesto de NP-completo.

+0

char * p = "char * p =% c% s% c; main() {printf (p, 34, p, 34);}"; main() {printf (p, 34, p, 34);} –

+0

¡Hola, guau! ¿Hiciste una variable con código? ¿Podemos hacerlo? – Ziggy

+0

Plase explicar "buscar lo opuesto f np-completo." ¿Seguramente lo dices al revés? –

8

Sure it is. ¡Así es como funcionan muchos virus!

+0

Vaya, me olvidé de eso :) –

+1

La mayoría de los virus no escriben código, simplemente copian ellos mismos o partes de sí mismos en el código existente. –

2

Sí, es posible crear generadores de código. La mayoría de las veces toman la entrada del usuario y producen un código válido. Pero hay otras posibilidades.

Programas de auto modificación también son posibles. Pero eran más comunes en la era del dos.

1

Existe toda una clase de tales elementos llamados "Generadores de código". (Aunque, un compilador también se ajusta a la descripción como lo configura). Y esos describen las dos áreas de estas bestias.

La mayoría de los códigos se generan, toman alguna forma de entrada de usuario (la mayoría toma un esquema de base de datos) y el código fuente del producto que luego se compila.

Los más avanzados pueden generar código ejecutable. Con .NET, hay un espacio de nombres completo (System.CodeDom) dedicado a la creación de código ejecutable. Con estos objetos, puede tomar el código C# (u otro idioma), compilarlo y vincularlo con su programa actualmente en ejecución.

3

Sí, ciertamente lo es, aunque tal vez no en el contexto al que se refiere, echa un vistazo a este post en t4.

2

¡Por supuesto que puede! De hecho, si usa un lenguaje dinámico, la clase puede cambiarse a sí misma (u otra clase) mientras el programa todavía se está ejecutando. Incluso puede crear nuevas clases que no existían antes. Esto se llama metaprogramación, y permite que su código sea muy flexible.

14

Si usted quiere aprender acerca de los límites de la computabilidad, leer acerca de la halting problem

En teoría de la computabilidad, la detención problema es un problema de decisión, que se puede expresar como sigue: dado una descripción de un programa y una entrada finita , decida si el programa termina de ejecutarse o se ejecutará para siempre, teniendo en cuenta esa entrada.

Alan Turing demostró en 1936 que un algoritmo general para resolver el problema de la parada para todos los posibles pares programa de entrada no puede existir

+0

Me acabas de ganar. +1 – Eclipse

+0

Afortunadamente, si el problema es limitado, es solucionable. –

1

Lo hago en PHP.

Para conservar la configuración de una clase, conservo una variable local llamada $data. $ data es solo un diccionario/hashtable/assoc-array (dependiendo de dónde vienes).

Cuando carga la clase, incluye un archivo php que básicamente define los datos. Cuando guardo la clase, escribe el PHP para cada valor de datos. Es un proceso de escritura lento (y actualmente hay algunos problemas de concurrencia) pero es más rápido que la lectura ligera. Mucho más rápido (y más ligero) que usar una base de datos.

Algo como esto no funcionaría para todos los idiomas. Funciona para mí en PHP porque PHP es mucho sobre la marcha.

2

Estás confundiendo/confundiendo dos significados de la palabra "escribir". Un significado es la escritura física de bytes en un medio, y el otro es el diseño de software. Por supuesto, puede hacer que el programa haga lo primero, si fue diseñado para hacerlo.

La única forma de que un programa haga algo que el programador no intenta explícitamente hacer es comportarse como una criatura viviente: mutar (incorporar partes del entorno) y replicar diferentes mutantes a diferentes velocidades (para evitar la extinción completa, si una mutación es terminal).

+0

Quise decir el primer significado, ¡pero me alegra su respuesta interesante! Recientemente volví a esta pregunta, pero cuando originalmente le pregunté, literalmente le pregunté si tenía un programa para copiar, cambiar la copia y luego ejecutar la copia (y luego, presumiblemente, finalizar). ¡Recientemente estoy más interesado en este segundo significado de escribir! – Ziggy

3

Si observa la Programación Funcional que tiene muchas oportunidades para escribir código que genera más código, la manera en que un lenguaje como Lisp no diferencia entre código y datos es una parte importante de su poder.

Rails genera varias clases predeterminadas de modelo y controlador desde el esquema de la base de datos cuando está creando una nueva aplicación. Es bastante estándar hacer este tipo de cosas con lenguajes dinámicos. Tengo algunos bits de PHP que generan archivos php, simplemente porque era la solución más simple al problema que estaba tratando en ese momento.

Así que es posible. Sin embargo, en cuanto a la pregunta que está haciendo, quizás sea un poco vaga, ¿qué entorno e idioma está utilizando? ¿Qué espera que haga el código y por qué necesita ser agregado? Un ejemplo concreto puede traer respuestas más directamente relevantes.

2

Sure it is. Escribí un efecto para Paint.NET * que le da un editor y le permite escribir un efecto gráfico "sobre la marcha". Cuando pausas al tipear, lo compila en un dll, lo carga y lo ejecuta. Ahora, en el editor, solo necesita escribir la función de representación real, todo lo demás necesario para crear un archivo DLL está escrito por el editor y enviado al compilador de C#.

se puede descargar gratis aquí: http://www.boltbait.com/pdn/codelab/

De hecho, no es ni siquiera una opción para ver todo el código que fue escrito para usted antes de ser enviada al compilador. El archivo de ayuda (vinculado arriba) habla sobre eso.

El código fuente está disponible para descargar desde esa página también.

* Paint.NET es un editor de imágenes gratuito que se puede descargar aquí: http://getpaint.net

+0

nice :) Siempre he querido codificar un efecto paint.net o gimp, pero no he tenido tiempo de mirarlo – Sophia

0

Esta es una de las cuestiones fundamentales de la inteligencia artificial. Personalmente, espero que no sea posible, de lo contrario, pronto me quedaré sin trabajo. :)

+0

¡O tal vez no tan pronto! – Ziggy

1

Siempre ha sido posible escribir generadores de código. Con la tecnología XML, el uso de generadores de código puede ser una herramienta esencial. Supongamos que trabaja para una empresa que tiene que tratar con archivos XML de otras compañías. Es relativamente sencillo escribir un programa que utiliza el analizador XML para analizar el nuevo archivo XML y escribir otro programa que tenga todas las funciones de devolución de llamada configuradas para leer archivos XML de ese formato. Todavía tendría que editar el nuevo programa para hacerlo específico a sus necesidades, pero el tiempo de desarrollo cuando un nuevo archivo XML (nueva estructura, nuevos nombres) se corta mucho utilizando este tipo de generador de código. En mi opinión, esto es parte de la fuerza de la tecnología XML.

2

hacer una copia del código fuente del programa que se ejecuta, modificar ese programa y añadir un método a la clase que sea, y luego ejecutar la copia del programa y termina en sí

Usted también puede generar código, compilarlo en una biblioteca en lugar de ser ejecutable, y luego cargar dinámicamente la biblioteca sin siquiera salir del programa que se está ejecutando actualmente.

+0

¡Guau! ¡Eso es exactamente lo que esperaba que pudiéramos hacer! – Ziggy

+1

Eso no necesariamente significa que sea una buena idea, aunque :-) –

2

Los lenguajes dinámicos generalmente no funcionan como usted sugiere, ya que no tienen un paso de compilación completamente separado. No es necesario que un programa modifique su propio código fuente, recompile y comience desde cero. Normalmente, la nueva funcionalidad se compila y se vincula sobre la marcha.

Common Lisp es un lenguaje muy bueno para practicar esto, pero hay otros en los que puede crear código y ejecutarlo en ese momento. Típicamente, esto será a través de una función llamada "eval" o algo similar. Perl tiene una función "eval", y generalmente es común que los lenguajes de scripting tengan la habilidad.

Hay muchos programas que escriben otros programas, como yacc o bison, pero no tienen la misma calidad dinámica que parece estar buscando.

4

Sí, eso es lo que hacen la mayoría de las macros Lisp (solo por un ejemplo).

1

Lisp Lisp Lisp Lisp: p

Bromas, si quieres código que genera código para funcionar y tienes tiempo que perder aprenderlo y rompiendo su mente con la materia recursiva generar más código, tratar de aprender Lisp :)

(eval '(or true false)) 
2

Eche un vistazo a Langtom's loop. Este es el ejemplo más simple de "programa" autorreproductor.

1

no sería bueno tener una clase que podría hacer una copia de la fuente del programa que se ejecuta, modificar ese programa y agregar un método a la clase que es, y luego ejecutar la copia de el programa y terminan en sí

casi no hay casos en los que podría resolver un problema que no puede resolverse "mejor" utilizando el código no auto-modificable ..

dicho esto, hay algunos muy comunes Casos (útiles) de código que escribe otro código. El más obvio es cualquier aplicación web del lado del servidor, que genera HTML/Javascript (bueno, HTML). es marcado, pero es idéntico en teoría). Además, cualquier secuencia de comandos que modifique un entorno de terminales suele generar un script de shell que evalúa el shell primario. wxGlade genera código para crear GUI bare-bone wx-based.

1

Vea nuestro DMS Software Reengineering Toolkit.Esta es una herramienta de uso general para leer y modificar programas, o generar programas mediante el ensamblaje de fragmentos.

Cuestiones relacionadas