pasaran / yate

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

Передача аргументов в apply и func #256

Open andychups opened 8 years ago

andychups commented 8 years ago

Привет!

Cмущает неконсистентная обработка аргументов в apply и func.

Поясните, пожалуйста, почему вызов функции и apply с передачей аргументов работают по-разному?

{ "value": "Test string value" }

https://f-o-r.github.io/yate-playground/?gistId=b23a3250a222c3bbfa4dd4ae1de85ecc

module "hello"

match / {
    apply . test1 (.value)
    <br/>
    apply . test2 (.value)
    <br/>
    fn(.value)
    <br />
    fn2(.value)
}

// 1 - используем apply и передаем nodeset без явного декларирования и получаем [object Object]
// в связи с приведением к скаляру
match .* test1 (arg) {
    arg
}

// 2 – используем apply, передаем nodeset, декларируем тип nodeset
// получаем Test string value
match .* test2 (nodeset arg) {
    arg
}

// 3 – используем func и получаем "Test string value", при том, что переданный nodeset превращается в скаляр внутри, но [Object Object] не выводится, т.к. применяется scalar2xml. Не ясно.
func fn(arg) {
    arg
}

// 4 – используем func, декларируем nodeset, получаем "Test string value" и это уже nodeset.
func fn2(nodeset arg) {
    arg
}
pasaran commented 8 years ago

Привет. Что-то пропустил письмо с уведомлением :(

Ну, тут понятно все. Когда вызывается apply, то неизвестно, в какой именно шаблон мы попадем в рантайме, может даже попадем в несколько шаблонов с разными типами аргументов. Поэтому статически привести аргументы к нужному типу невозможно. С функциями по-другому. Там на стадии компиляции сразу известно, что это за функция и какой тип аргументов она принимает. Поэтому в функциях можно передавать что угодно, оно по возможности приведется к нужному типу. А в шаблоны нужно сразу приводить к тому, что ожидаешь получить.

К сожалению, никак это не исправить, особенность динамического паттерн-матчинга. Вот еще такие же issues: https://github.com/pasaran/yate/issues/230 https://github.com/pasaran/yate/issues/64 https://github.com/pasaran/yate/issues/207