Groovy незадължителни скоби и точки

Уча Groovy и съм доста впечатлен от това как позволява да се изгради интелигентен DSL, но съм малко объркан от правилата за това кога скобите и точките не са задължителни. Разгледайте следния код:

Integer take(Integer x) {x}
take 3 plus 4

Това работи според очакванията и дава изход от 7 (когато се изпълнява в конзолата), тъй като groovy разбира последния ред като take(3).plus(4).

Сега println take 3 plus 4 не работи като groovy разбира това като println(take).3(plus).4, което е глупост.

Всеки пример, който виждам, показва тези изрази сами по себе си на ред, но очевидно

s = take 3 plus 4

работи и съхранява резултата 7 в s. Въпросът ми е защо

println( take 3 plus 4 )

не работа? Очевидно groovy ще анализира този вид изрази, дори ако те не са сами по себе си на ред (както е показано от работещото присвояване). Бих си помислил, че добавянето на тези скоби ще премахне неяснотата от формата на този ред, който не работи, и че ще отпечата 7, както възнамерявах.

Вместо това groovy дава грешка „неочакван токен: 3“. Доколкото мога да преценя, groovy няма да позволи незадължителни скоби или точки в този println, въпреки че не изглежда двусмислено. Кога точно работи този вид трик?


person Matthew    schedule 10.01.2016    source източник


Отговори (1)


Това попада в категорията на извикване на вложен метод и в този случай не можете да пропуснете скобите. Това причинява неяснота и резултатите са неочаквани, тъй като методът println смята, че му предавате множество параметъра. Можете да намалите неяснотата, като използвате groovy низ в метода println.

println "${take 3 plus 4}"

Повече информация: Изпускане на скоби

person dspano    schedule 11.01.2016
comment
Това би адресирало защо println take 3 plus 4 не работи, но не и защо println (take 3 plus 4) не работи, тъй като там не би трябвало да има никаква неяснота (ако трябваше да се тълкува като множество параметри, ще има запетая между тях, така че Groovy трябва да може да установете, че не това е имало предвид). Освен това тази връзка казва, че не трябва да работи и при присвояване (въпреки че примерът с код показва, че работи), но го прави. Чудя се дали това вече е малко остаряло. Ръководството за език не е толкова строго и предполага, че трябва да работи, когато е обвито като последната форма. - person Matthew; 12.01.2016
comment
+1 за това, че ми показа как мога да накарам това да работи в println, но не съм сигурен дали това отговаря напълно на въпроса ми. - person Matthew; 12.01.2016
comment
Това е двусмислено, защото методът println не знае как да оцени кода take 3 плюс 4 to take(3).plus(4) преди да извърши своята операция върху него. Всичко отдясно на знака „=“ е израз и се оценява преди да бъде присвоено на променливата. ${} казват първо да се оцени този код, след което да се извика println върху него. - person dspano; 12.01.2016
comment
Бих добавил, че това е ограничение на анализатора. Може би с antlr4 - person Will; 12.01.2016
comment
@WillP Благодаря ви за този коментар, той потвърждава това, което подозирах (или поне потвърждава, че други хора подозират същото). Има няколко места, където езиковата спецификация предполага, че това трябва да работи, но не е така. Ако спецификацията на езика представлява идеалната реализация, подозирам, че може да се окаже, че реализацията все още не може да изпълни всичко. Видях няколко урока в мрежата и книгата, от която се уча, казват, че това е ограничение на текущата версия и се надявам да бъде премахнато в по-късна версия. - person Matthew; 13.01.2016
comment
методът println не знае да оцени - кажете какво? хаха Не, вярвам, че това е основно ограничение на Groovy, по един или друг начин. Друго нещо, което открих, е, че println (или което и да е друго извикване на вложена функция) не трябва да се включва. Опитайте се да напишете това и компилацията е неуспешна: (take 3 plus 4). - person Martin Andersson; 07.03.2016
comment
@Matthew Интересен разговор. Този проблем все още не е решен в 2.4.10. Освен това изглежда има по-фундаментално ограничение: нищо общо с незадължителните точки; само незадължителни (или не в този случай) скоби. take 3 връща 3. (take 3) не се компилира. Вместо това трябва да напишете (take(3)). - person Klitos Kyriacou; 28.04.2017