2009-09-01 9 views
14

Podczas mojej rutynowej pracy, zdarzyło mi się napisać powiązaną funkcję javascript, która jest czymś podobnym do wyrażenia LINQ, aby zapytać o wynik JSON.Czy w JavaScript jest możliwe metaprogramowanie?

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

Działa idealnie i daje oczekiwany rezultat.

Zastanawiałem się, wygląda to super, jeśli kod jest napisany tak (w bardziej czytelny sposób)

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

czy jest jakiś sposób aby to osiągnąć ??

Cheers

Ramesh Vel

+4

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

+0

Możesz umieścić swój kod w jakimś tagu HTML lub pliku tekstowym. Wtedy możesz mieć własne DSL z Javascriptem ... – Philip

Odpowiedz

17

nr JavaScript nie obsługuje tej funkcji.

Ale wygląda to całkiem dobre: ​​

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

choć nie całkiem to, czego chciał, to jest możliwe napisanie parsera w javascript, i po prostu przetworzyć zapytania (przechowywane jako ciągi znaków), a następnie uruchom go. np. przy użyciu bibliotek takich jak http://jscc.jmksf.com/ (bez wątpienia istnieją inne) nie powinno być zbyt trudne do wdrożenia.

ale to, co masz w pytaniu, wygląda świetnie, nie jestem pewien, dlaczego chcesz, aby wyglądało tak, jak sugerujesz.

+0

dzięki za odpowiedź Chii .. Właściwie to właśnie eksperymentowałem z różnymi możliwościami. Jestem z tła C#, recentlty rozpoczęła się w javascript i po prostu chciałem zbadać funkcje JS ... to jest powód .. I dzięki za link .. Już rozglądałem się wokół parserów JS takich jak ten, o którym wspomniałeś .. i Znalazłem http://www.codeplex.com/jsinq jest przydatny .. dzięki znowu .. – RameshVel

1

Wat chcesz zmienić parser javascript na parser SQL. Nie został stworzony, aby to zrobić, składnia javascript nie pozwala na to.

To, co masz, jest w 90% podobne do SQL (mapuje bezpośrednio na niego) i 100% poprawny javascript, co jest świetnym osiągnięciem. Moja odpowiedź na pytanie w tytule brzmi: TAK, metaprogramowanie jest możliwe, ale NIE, nie da ci parsera SQL, ponieważ jest zobowiązany do używania gramatyki javascript.

6

Większość osób nalega na próbę metaprogramu z w swoim ulubionym języku w. To nie działa, jeśli język nie obsługuje dobrze metaprogramowania; inne odpowiedzi wykazały, że JavaScript tego nie robi.

Sposób obejścia tego polega na wykonaniu metaprogramowania od poza językiem, przy użyciu program transformation tools. Takie narzędzia mogą analizować kod źródłowy i przeprowadzać na nim dowolne transformacje (tak to robi metaprogramowanie), a następnie wypluć zmodyfikowany program.

Jeśli posiadasz uniwersalny system transformacji programów, który może analizować dowolne języki, możesz dokonać metaprogramowania na/w dowolnym języku. Zobacz nasze DMS Software Reengineering Toolkit dla takiego narzędzia, które ma solidne przednie końce dla C, C++, Java, C#, COBOL, PHP i ECMAScript i wiele innych języków programowania, i było używane do metaprogramowania na wszystkich z nich.

W twoim przypadku chcesz rozszerzyć gramatykę JavaScript o nową składnię zapytań SQL, a następnie przekształcić je w zwykły JavaScript. (Jest to bardzo podobne do programowania intencjonalnego) DMS z łatwością pozwoli ci zbudować dialekt JavaScript z dodatkowymi regułami, a następnie możesz użyć jego możliwości transformacji programu, by stworzyć równoważny standardowy Javascript.

Powiedziawszy, że nie jestem wielkim fanem "niestandardowej składni dla każdego programisty na świecie", czyli tam, gdzie intencjonalne programowanie prowadzi IMHO.

Jest to dobra rzecz, jeśli istnieje duża społeczność użytkowników, która uznałaby to za wartościowe. Ten pomysł może, ale nie musi być jednym z nich; Częścią problemu jest to, że nie można się dowiedzieć, bez eksperymentu, i może nie uzyskać wystarczającej społecznej trakcji.

3

Cóż, w próbce kodu:

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

Jedyny problem widzę (inne niż select używany jako identyfikator) jest to, że osadzić predykatu jako argument funkcji. Trzeba by zrobić to funkcja zamiast:

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

JavaScript ma zamknięć i dynamiczne pisanie, więc można zrobić kilka naprawdę ładne i eleganckie rzeczy w nim. Tylko cię informuję.

+0

dziękuję Joey, to dobry pomysł .. :) – RameshVel

2

W czystym JS nie, nie możesz. Ale z właściwym preprocesorem jest to możliwe.

Możesz zrobić coś podobnego z makrami sweet.js lub (Boże wybacz mi) GPP.

1

Biorąc pod uwagę, że to pytanie zadano kilka lat temu, postaram się dodać do niego więcej w oparciu o obecne technologie.

Począwszy od ECMAScript 6, metaprogramowanie jest teraz wspierane w pewnym sensie poprzez obiekty Symbol, Reflect i Proxy.

Przez wyszukiwanie w internecie, znalazłem szereg bardzo ciekawych artykułów na ten temat, napisany przez Keith Kirkel:

Metaprogramming in ES6: Symbols and why they're awesome

w skrócie Symbole są nowe prymitywy, które mogą być dodawane do środka obiektu (bez praktycznie właściwości) i są bardzo przydatne do przekazywania między innymi właściwości metaprogramowania. Symbole dotyczą zmiany zachowania istniejących klas poprzez ich modyfikację (odbicie w ramach implementacji).

Metaprogramming in ES6: Part 2 - Reflect

W skrócie, Reflect jest w rzeczywistości zbiorem wszystkich tych „metod wewnętrznych”, które były dostępne wyłącznie za pośrednictwem wewnętrznych silnika JavaScript, obecnie eksponowanych w jednym, poręcznym obiektu. Jego użycie jest analogiczne do możliwości Reflection Java i C#. Służą do odkrywania bardzo niskiego poziomu informacji na temat twojego kodu (Refleksja poprzez introspekcję).

Metaprogramming in ES6: Part 3 - Proxies

W skrócie, serwery proxy są Wózek obiekty odpowiedzialne do owijania przedmiotów i ich połączenia zachowania przez separatory (odbicie za przyczyną).

Oczywiście obiekty te zapewniają określone możliwości metaprogramowania, o wiele bardziej restrykcyjne w porównaniu do języków programowania metaprogramowania, ale wciąż mogą zapewnić przydatne sposoby na podstawowe metaprogramowanie, głównie poprzez praktyki Odbicia.

Na koniec warto wspomnieć, że istnieje kilka wartych zauważenia ongoing research work na etapowym metaprogramowaniu w JavaScript.

Powiązane problemy