В конференции CACHE_RU проходило обсуждение вопроса о возможности определить
является ли строка корректным списком CACHE'. Было выяснено при обобщении
информации поступившей из различных источников, что
Определить строение строки, формируемой списковыми функциями, не составляет большого труда, если воспользоваться командой zzdump. Просмотрев различные варианты списков, можно заметить, что список является конкатенацией тего-организованных структур, где каждый элемент начинается с длины, потом идет тип элемента, потом само значение, причем различные типы кодируются различным образом. Очевидно, это сделано с целью уменьшения объемов хранения. Списки оказались очень эффективны и применяются повсеместно. После некоторых размышлений я составил небольшую программку, определяющую является ли строка списком или нет. Программа составлена на М и проверялась на версии 3.2.2
Сама функция не производит детальный анализ строки, например строка
В целом же, в силу возможности применить функции $C() в любых вариантах, нет возможности точно сказать, была ли строка получена списковыми функциями или она так получилась в силу каких-то обстоятельств. В тех случаях, когда программа просмотра данных определит, что строка является корректным списком, но по контексту работы она получалась не списковыми операциями, программа может показать несписковую переменную как списковую. От такой проблемы, видимо, могут помочь только административные меры. Например, программа просмотра должна знать, что в определенных местах данные всегда не являются списками.
И, как обычно, если с приведенными мной кодами возникнут проблемы, прошу сообщить мне об этом.
Алексей Маслов (СП.АРМ, Санкт-Петербург) нашел ошибку в определении списочности списка $lb(-1), исправление внесено в код.
- Можно сформировать строку произвольного содержания, не пользуясь списковыми функциями
- Строка, сформированная списковыми функциями, ими же обрабатывается корректно
- В ситуации, когда строка сформирована несписковыми функциями, в некоторых случаях она может некоторыми функциями как список, а другими как не список
- Существуют строки, при определении которых на списочность процесс завершается аварийно
- Существуют программы, которые не могут определить происхождение строки и была ли она сформирована списковыми функциями или нет
- Спустя некоторое время представители фирмы Интерсистемс сообщили, что
исправления проблемы войдут в билд 5.0.5 и более поздние. Выдержка из внутренней
технической документации:
Prodlog Item 34439 Edited by Sorenson,Chuck ------------------------------------------------------------ MOST RECENT CHANGES: 4) 2003-10-31 16:58:09 Modified by Sorenson,Chuck DEVCHANGE changed to: CDS346 FIXER changed from: Unknown to: Sorenson,Chuck STATUS changed from: Dev to: Test COMMENT: I ported CDS346 and CDS405 to 5.0.6 build 1006 and 5.0.5 build 912.
- После довольно бурного обсуждения проблемы вопрос был объявлен модератором группы оффтопиком, поэтому все последующие его обсуждения следует производить вне группы CACHE_RU.
Определить строение строки, формируемой списковыми функциями, не составляет большого труда, если воспользоваться командой zzdump. Просмотрев различные варианты списков, можно заметить, что список является конкатенацией тего-организованных структур, где каждый элемент начинается с длины, потом идет тип элемента, потом само значение, причем различные типы кодируются различным образом. Очевидно, это сделано с целью уменьшения объемов хранения. Списки оказались очень эффективны и применяются повсеместно. После некоторых размышлений я составил небольшую программку, определяющую является ли строка списком или нет. Программа составлена на М и проверялась на версии 3.2.2
LL(val) ; вернуть длину списка если это список или -1 если нет i val="" q 0 n ret,i,sym,done,itemlen s ret=0,done=0,i=1 f q:done d . s sym=$e(val,i) . i sym="" s done=1 q . i sym=$c(0) d . . s sym=$e(val,i+1) i sym="" s done=1,ret=-1 q . . s itemlen=$a(sym) . . s sym=$e(val,i+2) i sym="" s done=1,ret=-1 q . . s itemlen=itemlen+($a(sym)*256) . . s sym=$e(val,i+3) i sym="" s done=1,ret=-1 q . . i $a(sym)>7 s done=1,ret=-1 q . . i $e(val,i+4)="" s done=1,ret=-1 q . e d . . s itemlen=$a(sym) . . q:itemlen=1 . . s sym=$e(val,i+1) i sym="" s done=1,ret=-1 q . . i $a(sym)>7 s done=1,ret=-1 q . . i ($a(sym)'=4)&($a(sym)'=1)&($a(sym)'=5) s sym=$e(val,i+2) . . i sym="" s done=1,ret=-1 q . q:done . i $l($e(val,i,i+itemlen-1))<itemlen s done=1,ret=-1 q . s i=i+itemlen . s ret=ret+1 q retФункция составлялась не в расчете на производительность работы, а на читабельность. Эта функция проверялась на наборе строк, которые и вызвали к жизни проблему, и на них показала правильные результаты. Если у Вас есть строки, которые штатными функциями определяются неправильно, то просьба проверить на них эту функцию.
Сама функция не производит детальный анализ строки, например строка
s str=$E($LB(1.2),1,3) s $e(str,1)=$c(3)определяется как список из одного элемента, но эта строка не может быть получена списковыми функциями:
USER>zzdump str 0000: 03 06 FF USER>w $li(str) 0 USER>zzdump $lb(0) 0000: 02 04 USER>zzdump $lb("0") 0000: 03 01 30 USER>zzdump $lb(0.0) 0000: 02 04 USER>w $listsame(str,$lb(0)) 1То есть при этом тем не менее списковые операции признают ее корректным списком из одного элемента число 0. Вполне возможно, что в некоторых случаях может понадобиться также и детальный анализ содержания элемента, например на предмет возможности его сформировать списковыми функциями.
В целом же, в силу возможности применить функции $C() в любых вариантах, нет возможности точно сказать, была ли строка получена списковыми функциями или она так получилась в силу каких-то обстоятельств. В тех случаях, когда программа просмотра данных определит, что строка является корректным списком, но по контексту работы она получалась не списковыми операциями, программа может показать несписковую переменную как списковую. От такой проблемы, видимо, могут помочь только административные меры. Например, программа просмотра должна знать, что в определенных местах данные всегда не являются списками.
И, как обычно, если с приведенными мной кодами возникнут проблемы, прошу сообщить мне об этом.
Алексей Маслов (СП.АРМ, Санкт-Петербург) нашел ошибку в определении списочности списка $lb(-1), исправление внесено в код.
Комментариев нет:
Отправить комментарий