2009-09-01 28 views
14

Durante mi trabajo rutinario, casualmente escribí la función javascript encadenada, que es algo así como la expresión LINQ para consultar el resultado JSON.¿Es posible la metaprogramación en Javascript?

var Result = from(obj1).as("x").where("x.id=5").groupby("x.status").having(count("x.status") > 5).select("x.status"); 

Funciona perfectamente y da el resultado esperado.

me preguntaba esto parece increíble si el código se escribe así (de una manera más legible)

var Result = from obj1 as x where x.status 
groupby x.status having count(x.status) > 5 
select x.status; 

hay una manera de lograr esto ??

Saludos

Ramesh Vel

+4

\ * cough \ * http://www.hugoware.net/Projects/jLinq \ * tos \ * –

+0

Puede poner su código en alguna etiqueta HTML o archivo de texto. Entonces puedes tener tu propia DSL con Javascript ... – Philip

Respuesta

17

Nº JavaScript no soporta esto.

Pero esto parece bastante bueno:

var Result = from(obj1) 
      .as("x") 
      .where("x.id=5") 
      .groupby("x.status") 
      .having(count("x.status") > 5) 
      .select("x.status"); 
5

aunque no es exactamente lo que quería, es posible escribir analizadores en javascript, y acaba de analizar la consulta (almacenados como cadenas) y luego ejecutarlo. Por ejemplo, utilizando bibliotecas como http://jscc.jmksf.com/ (sin duda hay otras por ahí) no debería ser demasiado difícil de implementar.

pero lo que tienes en la pregunta ya se ve muy bien, no estoy seguro de por qué quieres que luzca de la manera que sugeriste.

+0

gracias por la respuesta Chii ... En realidad solo estaba experimentando las diferentes posibilidades. Estoy con C# de fondo, recién comencé en Javascript y solo quería explorar las características de JS ... esa es la razón. Y gracias por el enlace. Ya he analizado los analizadores de JS como el que mencionaste ... y encontré que http://www.codeplex.com/jsinq es útil. Gracias de nuevo. – RameshVel

1

Wat que desea cambiar el analizador de JavaScript en un analizador de SQL. No fue creado para hacer eso, la sintaxis javascript no te permite hacerlo.

Lo que tiene es 90% como SQL (corresponde directamente), y un javascript 100% válido, que es un gran logro. Mi respuesta a la pregunta en el título es: SÍ, la metaprogramación es posible, pero NO le dará un analizador SQL, ya que está obligado a usar la gramática de JavaScript.

6

La mayoría de las personas insisten en tratar de metaprogramar desde dentro de su idioma favorito. Eso no funciona si el lenguaje no es compatible con la metaprogramación; otras respuestas han observado que JavaScript no lo hace.

Una forma de evitar esto es hacer metaprogramming de fuera la lengua, usando program transformation tools. Estas herramientas pueden analizar el código fuente y realizar transformaciones arbitrarias en él (eso es lo que hace la metaprogramación de todos modos) y luego escupir el programa revisado.

Si tiene un sistema de transformación de programa de propósito general, que puede analizar lenguajes arbitrarios, puede hacer metaprogramación en/con el lenguaje que desee. Consulte nuestra DMS Software Reengineering Toolkit para una herramienta de este tipo, que tiene extremos frontales robustos para C, C++, Java, C#, COBOL, PHP y ECMAScript y una cantidad de otros lenguajes de programación, y se ha utilizado para la metaprogramación de todos estos.

En su caso, desea extender la gramática de JavaScript con nueva sintaxis para las consultas SQL, y luego transformarlas a JavaScript simple. (Esto se parece mucho a la Programación intencional) DMS le permitirá construir fácilmente un dialecto de JavaScript con reglas adicionales, y luego puede usar sus capacidades de transformación de programas para producir el Javascript estándar equivalente.

Dicho esto, no soy un gran admirador de la "sintaxis personalizada para cada programador en el planeta", que es donde la Programación Intencional conduce en mi humilde opinión.

Esto es algo bueno que hacer si hay una gran comunidad de usuarios que encontraría esto valioso. Esta idea puede o no ser una de ellas; Parte del problema es que no puedes averiguarlo sin hacer el experimento, y puede que no consiga la suficiente tracción social como para importar.

3

Pues bien, en el ejemplo de código:

var Result = from(obj1) 
      .as("x") 
      .where("x.id=5") 
      .groupby("x.status") 
      .having(count("x.status") > 5) 
      .select("x.status"); 

El único problema que veo (que no sea select utilizado como identificador) es que incrusta un predicado como un argumento de la función. Habría que hacer una función en su lugar:

  .having(function(x){ return x.status > 5; }) 

Javascript cierres y tipado dinámico, por lo que puede hacer algunas cosas muy ingeniosas y elegantes en ella. Sólo para que lo sepas.

+0

gracias a Joey, esa es una buena idea ... :) – RameshVel

2

En JS puro no, no puedes. Pero con el preprocesador correcto es posible.

Puede hacer algo similar con sweet.js macros o (Dios me perdone) GPP.

1

Considerando que esta pregunta se ha formulado hace algunos años, intentaré agregarle más en función de las tecnologías actuales.

A partir de ECMAScript 6, la metaprogramación ahora es compatible en cierto sentido a través de los objetos Symbol, Reflect y Proxy.

Mediante la búsqueda en la web, he encontrado una serie de artículos muy interesantes sobre el tema, escrito por Keith Kirkel:

Metaprogramming in ES6: Symbols and why they're awesome

En pocas palabras, los símbolos son nuevas primitivas que se pueden agregar dentro de un objeto (sin prácticamente ser propiedades) y son muy útiles para pasarle propiedades de metaprogramación entre otras. Los símbolos tienen que ver con cambiar el comportamiento de las clases existentes al modificarlas (Reflexión dentro de la implementación).

Metaprogramming in ES6: Part 2 - Reflect

En resumen, Reflejar es efectivamente una colección de todos esos “métodos internos” que estaban disponibles exclusivamente a través de las partes internas del motor JavaScript, ahora expuestos en un solo objeto, muy práctico. Su uso es análogo a las capacidades de reflexión de Java y C#. Se utilizan para descubrir información de muy bajo nivel sobre su código (Reflexión a través de la introspección).

Metaprogramming in ES6: Part 3 - Proxies

En resumen, proxies son objetos de controlador, responsables de embalar objetos e interceptar sus comportamientos a través de trampas (reflexión a través de la intercesión).

Por supuesto, estos objetos proporcionan capacidades de metaprogramación específicas, mucho más restrictivas en comparación con los lenguajes de metaprogramación, pero aún así pueden proporcionar formas útiles de metaprogramación básica, principalmente a través de prácticas de Reflexión, de hecho.

Al final, vale la pena mencionar que hay algunos que vale la pena notar ongoing research work en metaprogramación por etapas en JavaScript.

Cuestiones relacionadas