Пользовательские функции в Evaluate()

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8031
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

Пользовательские функции в Evaluate()

Сообщение Игорь Столяров »

Привет всем !

Хотелось бы вернуться к обсуждению вопроса пользовательских функций в Evaluate()
и вообще к оптимизации его работы, раз это единственный вариант хоть как-то делать
выборки по пользовательским запросам в БД TPS при отсутствии SQL синтаксиса.

Можно ли как-то обойти запрет на использование "not be omittable" для параметров в забинденных функциях ?

Пример из жизни кроликов. ;)
Мне нужна элементарная функция MAX(Val1,Val2[,Val3][,Val4][,Val5]), которая вернет максимальной значение
от 2-х до 5-ти переданных в нее параметров. Алгоритмика работы самой функции проблем не представляет,
можно написать обработку любого ФИКСИРОВАННОГО кол-ва параметров.

Сейчас это выливается в то, что приходится выполнять, что то вроде MAX(Val1,MAX(Val2,MAX(Val3,Val4))) - что
кроме запутанного синтаксиса, думаю еще не лучшим образом влияет на производительность.

Хотя например те же функции Choose(), InList(), InRange() и т.д. внутри Evaluate() могут иметь переменное число параметров.

Значит это как-то сделать можно ?
Заранее спасибо за идеи ! ;)
Make Clarion Great Again ! 😎
kreator
✯ Ветеран ✯
Сообщения: 5161
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 11 раз
Поблагодарили: 26 раз

Пользовательские функции в Evaluate()

Сообщение kreator »

А почему не отказаться от omittable параметров? Всё равно параметры должны быть String, можно в функции проверять параметр на пустоту ('').
We are hard at work… for you. :)
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8031
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

Пользовательские функции в Evaluate()

Сообщение Игорь Столяров »

Мне, как худо-бедно программисту, конечно понятен синтаксис Max(11,12,34,'','') ...
Но пользователям думаю, что нет ... К тому же опять лишняя информация внутри Evaluate() ... :(
Make Clarion Great Again ! 😎
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

Пользовательские функции в Evaluate()

Сообщение Yufil »

До какой-то версии Кларион разрешалось указывать меньше параметров, недостающие замещались пробелами. Потом исправили :(. Я в разных проектах либо использовал свой препроцессор (писал что-то вида $Max x1,x2; с преобразованием в Max(x1,x2,-1,-1,-1) ), либо просто пользовал функции с разными именами (у меня есть Message, Message2, Message3 с разным комплектом параметров). Была идея с обратной записью и стеком, но и не сложилось...
kreator
✯ Ветеран ✯
Сообщения: 5161
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 11 раз
Поблагодарили: 26 раз

Пользовательские функции в Evaluate()

Сообщение kreator »

Попробовал на С10. Всё прокатило, с omittable параметрами. Подозреваю, что нельзя писать так:

Код: Выделить всё

Result = evaluate(Max(1,2,3,,5))
А вот так без проблем:

Код: Выделить всё

Result = evaluate(Max(1,2,3))
We are hard at work… for you. :)
Аватара пользователя
Дед Пахом
Старичок
Сообщения: 3289
Зарегистрирован: 07 Июль 2005, 16:51
Откуда: Москва, Россия
Благодарил (а): 15 раз
Поблагодарили: 49 раз
Контактная информация:

Пользовательские функции в Evaluate()

Сообщение Дед Пахом »

А что, перегруженные функции нельзя использовать?

Код: Выделить всё

Max(long, long), long
Max(long, long, long), long
Max(long, long, long, long), long
С уважением, ДП
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8031
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

Пользовательские функции в Evaluate()

Сообщение Игорь Столяров »

У меня как-то есть в подсознании (сам не знаю откуда !), что в Bind они не работают.
Сейчас попробую проверить наверняка ... Спасибо !
Make Clarion Great Again ! 😎
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8031
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

Пользовательские функции в Evaluate()

Сообщение Игорь Столяров »

Дед Пахом писал(а): А что, перегруженные функции нельзя использовать?
К сожалению не работает. Функции Overload сделать можно, без проблем.
Но когда мы биндим это имя функции, внутри Evaluate() мы видим только один вариант.
Судя по всему разбор схемы вызова overload procedure в зависимости от параметров выполняется
на этапе компиляции, а не в рантайме. По крайне мере не в рантайм Evaluate() - точно ! :(
Make Clarion Great Again ! 😎
kreator
✯ Ветеран ✯
Сообщения: 5161
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 11 раз
Поблагодарили: 26 раз

Пользовательские функции в Evaluate()

Сообщение kreator »

А мой вариант. У меня всё прокатило без всяких выкрутасов.
We are hard at work… for you. :)
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8031
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

Пользовательские функции в Evaluate()

Сообщение Игорь Столяров »

kreator писал(а): А мой вариант. У меня всё прокатило без всяких выкрутасов.
Спасибо. Класс ! Да это решает проблему.

До этого смотрел C63, а в справке С10 нас ждет приятный бонус:

With regards to EVALUATE, the evaluator is assuming a default value '' to all parameters in the function call in the expression string passed to EVALUATE. In other words, the prototype is assumed to be as follows:

myfunction (STRING='',STRING=''),STRING

and therefore actual parameters can be omitted in the expression.

Спасибо еще раз ! Пошел работать ... ;)
Make Clarion Great Again ! 😎
kreator
✯ Ветеран ✯
Сообщения: 5161
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 11 раз
Поблагодарили: 26 раз

Пользовательские функции в Evaluate()

Сообщение kreator »

Я, кстати, вот этот "десяточный приятный бонус" не понял. Просто попробовал.

Код: Выделить всё

Max                  PROCEDURE  (String v1, String v2, <String v3>, <String v4>, <String v5>) ! Declare Procedure
  CODE
if not omitted(3)
  if v3>v2 and v3>v1
    return v3
  else 
    return v2
  end
end
if v2>v1
  return v2
else
  return v1
end  
И вызов:

Код: Выделить всё

bind('Max', Max)
stop(evaluate(Max(5,6,9)))
unbind('Max')
Получается, что в C6.3 такая конструкция не работает? Тогда десятке очередной зачёт!
We are hard at work… for you. :)
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

Пользовательские функции в Evaluate()

Сообщение Yufil »

Проверил в Cw6, как опущенные, так и лишние параметры не работают
Кусок из старой программы.

Код: Выделить всё

BMsg                 PROCEDURE  (Loc:Msg)                  ! Declare Procedure
    CODE
    Message(Loc:Msg,'Внимание!',Icon:Asterisk)
    Return('')

BMsg2                PROCEDURE  (Loc:Msg,Loc:Title)        ! Declare Procedure
     CODE
      Message(Loc:Msg,Loc:Title,Icon:Asterisk)
    Return('')


Bind выполнен. 

            Bind('Msg',BMsg)
            Bind('Msg2',BMsg2)

Вызываю Evaluate(Bmsg('Привет')) => Message('Привет') 
               Evaluate(Bmsg('Привет', 'Привет2' )) => Errorcode
               Evaluate(Bmsg2('Привет', 'Привет2' )) => Message('Привет','Привет2') 
               Evaluate(Bmsg2('Привет' )) => Message('Привет')  => Errorcode

Правда, CW6.3, в 6.2 можно было пропускать поля. Сюрприз был ОЧЕНЬ неприятен...
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8031
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

Пользовательские функции в Evaluate()

Сообщение Игорь Столяров »

kreator писал(а): Я, кстати, вот этот "десяточный приятный бонус" не понял.
А не так все просто, как казалось ... В справке C10 об этом как-то туманно ...
Внутри Evaluate() параметры после 2 всегда возвращают Omitted() = True независимо от
их наличия при вызове, но при этом всегда имеют значение ...

Получается, что рабочий вариант в C10 будет выглядеть так:

Код: Выделить всё


! --- Расчет максимума от 2 до 5 значений для Evaluate() ---

Map
  Max_(String,String,<String>,<String>,<String>),Real
end  

Max_  Procedure(ZP1_,ZP2_,ZP3_,ZP4_,ZP5_)

Loc:xRetValue  Decimal(18,6)

  Code

  If (ZP1_ * 1) > (ZP2_ * 1) then Loc:xRetValue = ZP1_ else Loc:xRetValue = ZP2_.

  If ZP3_ <> ''
     If (ZP3_ * 1) > Loc:xRetValue then Loc:xRetValue = ZP3_.
     If ZP4_ <> ''
        If (ZP4_ * 1) > Loc:xRetValue then Loc:xRetValue = ZP4_.
        If ZP5_ <> ''
           If (ZP5_ * 1) > Loc:xRetValue then Loc:xRetValue = ZP5_.
        end
     end
  end

  Return(Loc:xRetValue)

Make Clarion Great Again ! 😎
kreator
✯ Ветеран ✯
Сообщения: 5161
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 11 раз
Поблагодарили: 26 раз

Пользовательские функции в Evaluate()

Сообщение kreator »

Игорь Столяров писал(а):Внутри Evaluate() параметры после 2 всегда возвращают Omitted() = True независимо от
их наличия при вызове, но при этом всегда имеют значение ...
В версии 11975 Omitted() отрабатывается правильно (когда надо True, когда надо False).
We are hard at work… for you. :)
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 8031
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 28 раз
Поблагодарили: 96 раз

Пользовательские функции в Evaluate()

Сообщение Игорь Столяров »

kreator писал(а): В версии 11975 Omitted() отрабатывается правильно (когда надо True, когда надо False).
Очень странно. Именно на этом релизе и проверял. Проверю еще раз. Спасибо.
Make Clarion Great Again ! 😎
Ответить