2009-09-01 10 views
14

Durante il mio lavoro di routine, mi è capitato di scrivere la funzione javascript concatenata che è qualcosa come l'espressione LINQ per interrogare il risultato JSON.La metaprogrammazione è possibile in Javascript?

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

Funziona perfettamente e fornisce il risultato previsto.

mi chiedevo questo sembra impressionante se il codice è scritto così (in un modo più leggibile)

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

c'è un modo per raggiungere questo ??

Acclamazioni

Ramesh Vel

+4

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

+0

È possibile inserire il codice in un tag HTML o in un file di testo. Quindi puoi avere il tuo DSL con Javascript ... – Philip

risposta

17

No. JavaScript non supporta questa.

Ma questo sembra abbastanza buono troppo:

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

anche se non del tutto quello che volevi, è possibile scrivere parser in javascript, e basta analizzare la query (memorizzati come stringhe) e poi eseguirlo. ad esempio, utilizzando librerie come http://jscc.jmksf.com/ (senza dubbio ce ne sono altre là fuori) non dovrebbe essere troppo difficile da implementare.

ma quello che hai nella domanda sembra già ottimo, non sono sicuro del motivo per cui vorresti che fosse simile a quello che hai suggerito.

+0

grazie per la risposta Chii .. In realtà stavo solo sperimentando le diverse possibilità. Sono con lo sfondo C#, recentlty iniziato in javascript e volevo solo esplorare le funzionalità JS ... questo è il motivo .. E grazie per il link .. ho già guardato intorno ai parser JS come quello che hai menzionato .. e ho trovato http://www.codeplex.com/jsinq è utile .. grazie ancora .. – RameshVel

1

Si desidera modificare il parser javascript in un parser SQL. Non è stato creato per farlo, la sintassi javascript non ti permette di farlo.

Quello che hai è il 90% come SQL (si dirige direttamente su di esso), e un javascript valido al 100%, che è un grande risultato. La mia risposta alla domanda nel titolo è: SÌ, la metaprogrammazione è possibile, ma NO non fornirà un parser SQL, poiché è destinato all'utilizzo della grammatica javascript.

6

La maggior parte delle persone si ostina a provare a metaprogrammare da all'interno della lingua preferita. Ciò non funziona se la lingua non supporta bene la metaprogrammazione; altre risposte hanno osservato che JavaScript no.

Un modo per aggirare questo è quello di fare metaprogrammazione da di fuori la lingua, utilizzando program transformation tools. Tali strumenti possono analizzare il codice sorgente ed eseguire trasformazioni arbitrarie su di esso (questo è quanto fa comunque la metaprogrammazione) e quindi sputare il programma revisionato.

Se si dispone di un sistema di trasformazione di programmi generici, in grado di analizzare lingue arbitrarie, è possibile eseguire metaprogrammazione su/con qualsiasi lingua desiderata. Guarda il nostro DMS Software Reengineering Toolkit per un tale strumento, che ha robusti front-end per C, C++, Java, C#, COBOL, PHP e ECMAScript e un numero di altre lingue di programmazione, ed è stato usato per metaprogrammazione su tutti questi.

Nel tuo caso, si desidera estendere la grammatica JavaScript con nuova sintassi per le query SQL e quindi trasformarle in semplice JavaScript. (Questo è molto simile alla programmazione intenzionale) DMS ti consente di creare facilmente un dialetto JavaScript con regole aggiuntive, quindi puoi utilizzare le sue capacità di trasformazione del programma per produrre lo standard Javascript equivalente.

Detto questo, non sono un grande fan della "sintassi personalizzata per ogni programmatore del pianeta", che è il punto in cui la programmazione intenzionale porta IMHO.

Questa è una buona cosa da fare se c'è una grande comunità di utenti che troverebbe questo prezioso. Questa idea può o non può essere una di queste; parte del problema è che non riesci a scoprirlo senza fare l'esperimento, e potrebbe non riuscire ad acquisire una sufficiente trazione sociale per la questione.

3

Ebbene, nel codice di esempio:

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

L'unico problema che vedo (diverso da select usato come un identificatore) è che si incorpora un predicato come argomento di funzione. Dovreste farne una funzione invece:

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

Javascript deve chiusure e tipizzazione dinamica, in modo da poter fare alcune cose davvero nifty ed eleganti in esso. Solo per farti sapere.

+0

grazie Joey, questa è una buona idea .. :) – RameshVel

2

In puro JS no non è possibile. Ma con il giusto preprocessore è possibile.

Si può fare qualcosa di simile con i macro sweet.js o (Dio perdonami) GPP.

1

Considerando che questa domanda è stata posta qualche anno fa, cercherò di aggiungervi altro in base alle tecnologie attuali.

A partire da ECMAScript 6, la metaprogrammazione è ora supportata in un certo senso tramite gli oggetti Symbol, Reflect e Proxy.

Effettuando una ricerca sul web, ho trovato una serie di articoli molto interessanti sul tema, scritto da Keith Kirkel:

Metaprogramming in ES6: Symbols and why they're awesome

In breve, I simboli sono nuove primitive che possono essere aggiunti all'interno di un oggetto (senza praticamente essere proprietà) e sono molto utili per passare le proprietà di metaprogrammazione ad esso tra gli altri. I simboli consistono nel modificare il comportamento delle classi esistenti modificandole (Riflessione nell'implementazione).

Metaprogramming in ES6: Part 2 - Reflect

In breve, riflettere è effettivamente un insieme di tutti questi “metodi interni” che erano disponibili esclusivamente attraverso le parti interne del motore JavaScript, ora esposte in un unico oggetto pratico. Il suo utilizzo è analogo alle capacità di Reflection di Java e C#. Sono usati per scoprire informazioni di livello molto basso sul tuo codice (Riflessione attraverso l'introspezione).

Metaprogramming in ES6: Part 3 - Proxies

In breve, Proxy sono oggetti gestori, responsabili per avvolgere gli oggetti e intercettando loro comportamenti attraverso trappole (Reflection attraverso intercessione).

Ovviamente, questi oggetti forniscono capacità di metaprogrammazione specifiche, molto più restrittive rispetto ai linguaggi di metaprogrammazione, ma possono comunque fornire metodi pratici di metaprogrammazione di base, principalmente attraverso le pratiche di riflessione.

Alla fine, vale la pena ricordare che c'è qualcosa che vale la pena notare ongoing research work sulla metaprogrammazione a fasi in JavaScript.

Problemi correlati