pasaran / yate

Yet Another Template Engine
MIT License
214 stars 28 forks source link

Кастомные функции jpath #172

Open jbinary opened 11 years ago

jbinary commented 11 years ago

Можно ли поиметь возможность дёргать из jpath кастомные функции? Например:

filtered = contacts[contains(.nick, filter_string)]
pasaran commented 11 years ago

В общем это возможно, используя внешние функции.

Если коротко, то как-то вот так:

https://github.com/pasaran/yate/blob/master/tests/functions.21.yate https://github.com/pasaran/yate/blob/master/tests/functions.21.js

Т.е. в .yate-шаблоне нужно объявить функцию как внешнюю, указав возвращаемый тип и типы аргументов:

external nodeset contains(nodeset, scalar)

И определить в js эту функцию примерно так:

//  Если дело происходит в ноде, нужна такая строчка
//  var yr = require('yate/lib/runtime.js');

yr.externals.contains = function(nodeset, scalar) {
    ...
};
jbinary commented 11 years ago

Хм. Я так примерно и думал, но не стал проверять вот почему: у меня есть функция, но не внешняя:

func get_contact_display(nodeset contact) {                                    
    if contact.nick {                                                          
        "{ contact.nick }"                                                     
    } else {                                                                   
        get_contact_jid(contact)                                               
    }                                                                          
}

и вот так использовать её не получилось:

filtered = contacts[get_contact_display(.) == filter_string]

В итоге оказалось, что мне, в данном случае, такое и не нужно, а проверить external функцию я что-то постеснялся, но, в принципе, интересно на будущее, возможен ли и так выкрутас.

Когда проверю external функцию, закрою тикет, большое спасибо за ответ.

pasaran commented 11 years ago

Хмм. Вообще-то по идее должно и с обычной функцией работать. А что именно не получилось?

pasaran commented 11 years ago

По крайней мере, какой-то тест на эту тему есть https://github.com/pasaran/yate/blob/master/tests/functions.17.yate

jbinary commented 11 years ago
/usr/lib64/node_modules/yate/lib/asts.js:119
            if ( items[i][callback]() ) { return true; }
                                   ^
TypeError: Object if_( scalar )
[дерево поскипано]
    Cid: 0 has no method 'isLocal'
    at yate.asts.items.someIs (/usr/lib64/node_modules/yate/lib/asts.js:119:36)
    at yate.asts.items.isLocal (/usr/lib64/node_modules/yate/lib/asts.js:234:17)
    at yate.asts.block.isLocal (/usr/lib64/node_modules/yate/lib/asts.js:479:25)
    at yate.asts.body.isLocal (/usr/lib64/node_modules/yate/lib/asts.js:305:25)
    at yate.asts.function_.isLocal (/usr/lib64/node_modules/yate/lib/asts.js:904:24)
    at yate.asts.inline_function.isLocal (/usr/lib64/node_modules/yate/lib/asts.js:2138:21)
    at yate.asts.inline_op.isLocal (/usr/lib64/node_modules/yate/lib/asts.js:1631:24)
    at yate.asts.jpath_predicate.isLocal (/usr/lib64/node_modules/yate/lib/asts.js:2431:24)
    at yate.asts.jpath_predicate.w_setTypes (/usr/lib64/node_modules/yate/lib/asts.js:2439:14)
    at /usr/lib64/node_modules/yate/lib/actions.js:125:13
pasaran commented 11 years ago

А можешь запостить весь .yate-файл? Или какую-то его небольшую часть, но так чтобы воспроизводилась ошибка? Я посмотрю.

On Wed, Apr 24, 2013 at 4:49 PM, Sergey Dobrov notifications@github.comwrote:

/usr/lib64/nodemodules/yate/lib/asts.js:119 if ( items[i][callback]() ) { return true; } ^ TypeError: Object if( scalar ) [дерево поскипано] Cid: 0 has no method 'isLocal' at yate.asts.items.someIs (/usr/lib64/node_modules/yate/lib/asts.js:119:36) at yate.asts.items.isLocal (/usr/lib64/node_modules/yate/lib/asts.js:234:17) at yate.asts.block.isLocal (/usr/lib64/node_modules/yate/lib/asts.js:479:25) at yate.asts.body.isLocal (/usr/lib64/nodemodules/yate/lib/asts.js:305:25) at yate.asts.function.isLocal (/usr/lib64/node_modules/yate/lib/asts.js:904:24) at yate.asts.inline_function.isLocal (/usr/lib64/node_modules/yate/lib/asts.js:2138:21) at yate.asts.inline_op.isLocal (/usr/lib64/node_modules/yate/lib/asts.js:1631:24) at yate.asts.jpath_predicate.isLocal (/usr/lib64/node_modules/yate/lib/asts.js:2431:24) at yate.asts.jpath_predicate.w_setTypes (/usr/lib64/node_modules/yate/lib/asts.js:2439:14) at /usr/lib64/node_modules/yate/lib/actions.js:125:13

— Reply to this email directly or view it on GitHubhttps://github.com/pasaran/yate/issues/172#issuecomment-16924079 .

jbinary commented 11 years ago

Сделаю сегодня-завтра тест тогда. Надо будет ещё yate обновить заодно, мало ли что.

jbinary commented 11 years ago

тест в #173

pasaran commented 11 years ago

Так. Я собрал 0.0.42 В ней я поправил кое-что. Теперь тест компилируется. Но выдает неправильный результат. Мне вот кажется, что в тесте ошибка. Вторая группа тоже есть (но пустая). Тест слишком сложный, конечно. Кажется, там дело в том, что в предикате использовалась функция, состаящая из if'а (или содержащая if).

jbinary commented 11 years ago

А что выдаёт тест?

jbinary commented 11 years ago

Вообще, ты прав, в тесте ошибка, надо вывод имени группы перенести туда, где уже можно узнать, есть ли filtered_contacts хоть один, и выводить только, если есть.

jbinary commented 11 years ago

Если надо, давай исправлю, и заодно ещё упрощу тест?

pasaran commented 11 years ago

Да, упрости и исправь плз )