powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / FastScript, кэширование параметров
25 сообщений из 26, страница 1 из 2
FastScript, кэширование параметров
    #39769406
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обнаружил неприятную хрень.
В FS создаем пару процедур, одинаковых:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
function Test1(aValue : boolean = false) : string;
begin
  result := iif(aValue, 'True', 'False');                                     
end;            
  

function Test2(aValue : boolean = false) : string;
begin
  result := iif(aValue, 'True', 'False');                                     
end;            



Тестируем их:
Код: pascal
1.
  ShowMessage(Test1(True) + ' ' + Test2(False));



Наблюдаем:
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39769409
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фэйтл Эра,

причину нашел: кэширование параметров в iif(). Параметром в данном случая является строка 'aValue'.
Если имена формальных параметров Test1() и Test2() будут разными - глюк не проявится.


У меня FastScript v1.9 (в составе FR4.12). Если не сложно, проверьте в новых версиях FS/FR.
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39769410
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посмотрел: ну да, эта функция - не встроенная в FS, а экспортирована в методе PrepareScript() класса TfrxReport.

Тем не менее - проверьте, пожалуйста, как работает iif(,,) в новых (5.*, 6.*) FR.

Спасибо.
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39769416
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Только что скачал демку 6.0: https://www.fastreport.ru/ru/download/public_download/fr6_demo.exe
Инсталлировал, запустил.
Выбрал раздел "Dialogs and Script", выбрал отчет "Hello Fast Report", нажал Design.
Добавил к скрипту код из 21801580 . Все то же самое.

Это п....ц, товарищи. .
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39769419
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кто мешает переопределить функцию ?
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39769422
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaBrКто мешает переопределить функцию ?

Да никто, теперь-то. Но я вот полдня потратил на локализацию бага. Не стоило сюда сообщать?

И там не только iif(,,). Непонятно, когда взорвется.
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39769779
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Фэйтл Эра,

Это специфика работы функций объявленных как 'macrofunction' , они предназначены для работы в выражениях.
Самый лучшей вариант в вашем случае сделать свою функцию для скриата (iif_s(...) ).
На моей памяти вы первый у кого "взорвалось", условия воспроизведения специфичные.
Таких функций всего 6, пять из которых агрегаты. Агрегаты под такими условиями не будут работать никак, т.к. выражение агрегата в скрипте должно совпадать с выражением в мемо(в документации это описано). Поэтому использовать в качестве параметра какой нибудь aValue там не выйдет. Т.е. поймать это можно только с iif.

В целом, ситуация конечно не красивая, пометил чтобы добавили в документацию о данной специфике.
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39769821
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Den_Z_...пометил чтобы добавили в документацию о данной специфике.
А нельзя ли здесь "о специфике" iif(,,) объяснить?
Не рекомендуется в качестве параметров iif(,,) использовать повторяющиеся имена параметров методов, - или что?
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39769850
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Давным давно написал и забыл
Код: pascal
1.
TfsMethodHelper(Find('IIF')).OnCallNew := CallMethod;
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39770810
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Фэйтл Эра,

macrofunction передают в качестве параметров строку выражения, а не значение вычисленного выражения скриптом.
Это сделано что такие выражения можно было кешировать. Внутри скрипта такое делать смысла нет - синтаксический разбор делается один раз.
В объектах вычисление выражений происходит по GetData, т.е. фактически на каждый вывод бэнда, чтобы не делать разбор выражений каждый раз они кешируются по имени. Поэтому я и не советую делать как описали выше , с подменой функции. Если в мемо на мастер бэнде будет простое выражение IIF, а бенд повторяется 10000 раз, то вычисления в обход кеширования замедлит отчет (т.к. каждый раз будет происходить разбор синтаксиса).

Выражения в объектах выполняются относительно глобальной процедуры скрипта, т.е. их область видимости глобальный скрипт.
Выполнение макрофункции в локальной процедуре делает разбор и кеширование относительно ее области видимости, и записывает в кеш ссылку на разобранное выражение относительно имени (разобранное <> вычисленное). При повторном появлении такого же выражения оно не разбирается второй раз, а просто вычисляется значение. Поэтому привязка в вашем примере идет к первому разобранному выражению с данным именем(aValue в Test1).

Тут можно сделать костыль проверяя относительно чего выполняется макрофункция, но эффективность кеша снизится и это будет откровенный костыль. Поэтому проще объявить свою функцию для использования в скрипте, а не в выражениях объектов.
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39770823
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Den_Z_Выражения в объектах выполняются относительно глобальной процедуры скрипта, т.е. их область видимости глобальный скрипт.
Выполнение макрофункции в локальной процедуре делает разбор и кеширование относительно ее области видимости, и записывает в кеш ссылку на разобранное выражение относительно имени (разобранное <> вычисленное). При повторном появлении такого же выражения оно не разбирается второй раз, а просто вычисляется значение.

У вас точно с логикой проблемы.
"Область видимости" второй раз - совсем другая процедура. Если вызвать второй раз не вторую, а первую процедуру, то все "разбирается" заново. А вторую - сколько ни вызывай, из кэша берётся:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
function Test1(aValue : boolean) : string;
begin
  result := iif(aValue, 'True', 'False');                                     
end;            
  

function Test2(aValue : boolean) : string;
begin
  result := iif(aValue, 'True', 'False');                                     
end;              
...
begin
  ShowMessage('Test1: ' + Test1(True)  + Test1(False) + Test1(True)   + Test1(False)
              +#10                                                    
            + 'Test2: ' + Test2(True)  + Test2(True)  + Test2(True)   + Test2(True)                
              +#10
            + 'Test1: ' + Test1(False) + Test1(True)  +  Test1(False) + Test1(True)               
              +#10
            + 'Test2: ' + Test2(False) + Test2(False) + Test2(False)  + Test2(False)                    
              +#10
            + 'Test1: ' + Test1(False) + Test1(True)  +  Test1(False) + Test1(True)               
            );
...
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39770830
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Den_Z_Тут можно сделать костыль проверяя относительно чего выполняется макрофункция, но эффективность кеша снизится и это будет откровенный костыль...

Совсем обалдели, что ли. Функция вычисляется НЕПРАВИЛЬНО, а вы об эффективности рассказываете.
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39770860
DimaBr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Den_Z_В объектах вычисление выражений происходит по GetData, т.е. фактически на каждый вывод бэнда, чтобы не делать разбор выражений каждый раз они кешируются по имени. Поэтому я и не советую делать как описали выше , с подменой функции. Если в мемо на мастер бэнде будет простое выражение IIF, а бенд повторяется 10000 раз, то вычисления в обход кеширования замедлит отчет (т.к. каждый раз будет происходить разбор синтаксиса).
Как по мне, уж лучше 10000 раз проходит разбор выражения, чем неверный результат
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39770869
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Фэйтл ЭраУ вас точно с логикой проблемы.
"Область видимости" второй раз - совсем другая процедура. Если вызвать второй раз не вторую, а первую процедуру, то все "разбирается" заново. А вторую - сколько ни вызывай, из кэша берётся:

Так ваш пример и показывает, что всегда используется значения первой функции.
Специально выделю:
'Test1: ' + Test1(True) + Test1(False) + Test1(True) + Test1(False) - (Test1(aValue) = False)
+#10
+ 'Test2: ' + Test2(True) + Test2(True) + Test2(True) + Test2(True)
+#10
+ 'Test1: ' + Test1(False) + Test1(True) + Test1(False) + Test1(True) - (Test1(aValue) = True)
+#10
+ 'Test2: ' + Test2(False) + Test2(False) + Test2(False) + Test2(False)
+#10
+ 'Test1: ' + Test1(False) + Test1(True) + Test1(False) + Test1(True)

Это интерпретатор, он не сбрасывает переменные после выхода из процедуры, значение по умолчанию устанавливаются при заходе в нее.

Фэйтл ЭраСовсем обалдели, что ли. Функция вычисляется НЕПРАВИЛЬНО, а вы об эффективности рассказываете.
Я рассказываю для чего предназначена функция.
Функция IIF предназначена для использования в выражениях объектов, а не в скрипте.
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39770874
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Den_Z_Функция IIF предназначена для использования в выражениях объектов, а не в скрипте.

ОК.
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39770880
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Фэйтл Эра_Den_Z_Функция IIF предназначена для использования в выражениях объектов, а не в скрипте.

ОК.
Я не сказал что мы ничего с этим делать не будем, ошибка мне не нравится и у пользователей могут быть сотни отчетов с IIF внутри скрипта. Вы спросили как оно работает и почему, я написал.
Набросал временное решение. Оно пойдет в дневной билд 6ки. Но в этих местах мало что менялось, поэтому можно перетянуть и на 4ку, diff прицепил.
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39770884
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Den_Z_,

спасибо.
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39770888
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот еще. Смешно. "Кэширование" не учитывает регистр.

Код: pascal
1.
2.
3.
4.
5.
      ShowMessage('Прописные буквы, "правда": ' + iif(True,    'ПРАВДА', 'ЛОЖЬ')         
             + #10'Прописные буквы, "ложь":   ' + iif(False,   'ПРАВДА', 'ЛОЖЬ')
             + #10'Строчные буквы, "правда":  ' + iif(True,    'правда', 'ложь')         
             + #10'Строчные буквы, "ложь":    ' + iif(False,   'правда', 'ложь')               
             );
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39770889
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фэйтл ЭраВот еще. Смешно. "Кэширование" не учитывает регистр.

Код: pascal
1.
2.
3.
4.
5.
      ShowMessage('Прописные буквы, "правда": ' + iif(True,    'ПРАВДА', 'ЛОЖЬ')         
             + #10'Прописные буквы, "ложь":   ' + iif(False,   'ПРАВДА', 'ЛОЖЬ')
             + #10'Строчные буквы, "правда":  ' + iif(True,    'правда', 'ложь')         
             + #10'Строчные буквы, "ложь":    ' + iif(False,   'правда', 'ложь')               
             );





Начал просматривать старые отчеты, где в скрипте есть iif(,,) /*да везде почти есть*/, нашел, что в заголовке должно быть напечатано 'подряд' или 'хозспособ', а в подвале - 'Подряд' или 'Хозспособ' соответственно (с прописными буквами в начале), но нет - печатает, как в заголовке, только строчными. Никто и не жаловался - "подумашь, мелочь".
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39770892
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Den_Z_...
Набросал временное решение. Оно пойдет в дневной билд 6ки. Но в этих местах мало что менялось, поэтому можно перетянуть и на 4ку, diff прицепил.

https://www.sql.ru/forum/actualfile.aspx?id=21803941] Приложенный файл (Diff.zip - 2Kb)

Переношу в свой (FR 4.12) код, тестирую iif(,,). Никакой разницы, те же глюки.

Смотрю. Реализацию "макро" метода iif() не поменяли. Хм.
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39770914
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Den_Z_,

жесть, из алгоритмистов кто-то смотрит это безобразие?
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39770961
gpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фэйтл ЭраВот еще. Смешно. "Кэширование" не учитывает регистр.

Код: pascal
1.
2.
3.
4.
5.
      ShowMessage('Прописные буквы, "правда": ' + iif(True,    'ПРАВДА', 'ЛОЖЬ')         
             + #10'Прописные буквы, "ложь":   ' + iif(False,   'ПРАВДА', 'ЛОЖЬ')
             + #10'Строчные буквы, "правда":  ' + iif(True,    'правда', 'ложь')         
             + #10'Строчные буквы, "ложь":    ' + iif(False,   'правда', 'ложь')               
             );


Код: pascal
1.
TfrxReport.CaseSensitiveExpressions := True;
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39771037
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Фэйтл Эра,

Так реализация и не поменялась, поменялся кеш.
Для IIF он теперь пишет выражение в кеш относительно функции которой выполняется, т.е. 'ИмяФункции.' + Выражение.
Если не получится перенести, могу скинуть функции целиком.
Работоспособность можно проверить на текущей демке.

Про чувствительность к регистру уже написали, за это отвечает frxReport.CaseSensitiveExpressions.

kealon(Ruslan) ,
Легаси код постепенно переписываться. Это минное поле в котором исправление казалось бы очевидного бага ведет к отваливанию отчетов у сотни пользователей, т.к. они в тихую использовали этот баг.
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39771259
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Den_Z_, в fr 4.12, после применения указанного diff-а поведение не изменилось. Может быть, версия FR у меня слишком "не новая".
...
_Den_Z_...
Про чувствительность к регистру уже написали, за это отвечает frxReport.CaseSensitiveExpressions.
...
Хоть как-то оправдывать поведение ( 21803962 ) - это забавно.

Да и TfrxReport.CaseSensitiveExpressions property появился только в FR 4.3. Да и применять TfrxReport.CaseSensitiveExpressions в данном контексте - это уже совсем надо быть "ку-ку".
...
Рейтинг: 0 / 0
FastScript, кэширование параметров
    #39771295
_Den_Z_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Фэйтл Эра,

Так я нигде и не оправдываю этот кривой легаси код, я вам пишу как можно на конкретной версии это обойти.

Присылайте свои frxClass.pas и fs_iintepriter.pas , не видя конкретной версии не могу сказать куда и что вставлять.
Можно на почту den@Имя_домена_фр.com
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / FastScript, кэширование параметров
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]