|
|
#1 |
|
Участник
|
Проверка на RecId
Привет.
Возник следующий вопрос: Есть код: Table1 table1 = Table1::find(_Key); далее проверка, которую можно выполнить двумя способами ; if (table1) { ..... } и if(table1.recId) { ... } Является ли первый способ корректным? |
|
|
|
|
#2 |
|
Участник
|
в первом, насколько я понимаю, способе происходит неявное преобразование типов.
при преобразовании Common -> Int, Аксапта самостоятельно подставляет recID. Поэтому, сейчас технически работают оба способа. Рекомендуется использовать второй. (Рекомендацию видел где-то в презентациях, где точно уже не помню) |
|
|
|
|
#3 |
|
Administrator
|
Только не Common в int, а Common в boolean.
Во втором случае тоже преобразовние: int в boolean Чтобы быть уверенным на 110%, пишите if (table1.RecId != 0) { ... }
__________________
Not registered yet? Register here! Have comments, questions, suggestions or anything else regarding our web site? Don't hesitate, send them to me |
|
|
|
|
#4 |
|
Участник
|
Цитата:
Изначально опубликовано Maxim Gorbunov
Только не Common в int, а Common в boolean. |
|
|
|
|
#5 |
|
Участник
|
Категорически не соглашусь с "мэтрами"
:1. Правила по преобразованию примитивных типов к логическому выражению в условиях, которые X++ унаследовал от C/C++ никто и никогда отменять не будет. Чётко и ясно сказано что нулевое значение аргумента воспринимается компилятором как false, а ненулевое - true, сомневаться в этом - значит проявлять незнание языка и плодить излишне перегруженный конструкциями код. if ( a )... всегда было и будет предпочтительнее чем if ( a != 0 ) так же как и if ( !( a < b ) ) выглядит запутаннее и непонятнее, чем if ( a >= b ) (кстати в практике программирования на 1С встречал следующий код: Если НЕ(ОсталосьСписать>0) Тогда Прервать; КонецЕсли; долго смеялся )2. То же самое касается и преобразования Common в boolean. if ( tbl ) выглядит гораздо проще и интуитивно понятнее чем if ( tbl.RecId ) Чем обоснованы рекомендации предпочитать tbl.RecId мне непонятно, ведь если когда нибудь правило преобразования Common в boolean хотя бы слегка изменят, половина кода аксапты станет неработоспособной, посему его никогда не изменят. В общем я предпочитаю if ( table1 ) ![]() Хотя в принципе всё это вопрос вкуса и относится к той же теме что и вопрос о том звёздочками или плюсиками лучше помечать блоки комментариев в коде. |
|
|
|
|
#6 |
|
----------------
|
Проверка If(table) более интеллектуальна, чем проверка If(table.RecID).
Например, после агрегации и ограничения списка выбираемых полей возможна ситуация, когда RecId = 0, но If(table) = true Для проверки после find, действительно, нет разницы как проверять наличие результата. |
|
|
|
|
#7 |
|
NavAx
|
уже довольно давно правил такой код на форме накладных:
PHP код:
только исправление на: PHP код:
Это конечно же не конструкция if, но все равно аргумент должен приводиться к логическому типу
__________________
Чудес не бывает (c), истина где-то рядом (c)... |
|
|
|
|
#8 |
|
Участник
|
флуд
Цитата:
Чётко и ясно сказано что нулевое значение аргумента воспринимается компилятором как false, а ненулевое - true, сомневаться в этом - значит проявлять незнание языка и плодить излишне перегруженный конструкциями код.
Какой компилятор может быть во время выполения?
__________________
Уточните значение слов и вы избавите человечество от половины его заблуждений. (Рене Декарт) / Axapta 2.5 |
|
|
|
|
#9 |
|
Участник
|
Цитата:
...
FactureEditLinesCust_RU.enabled(CustInvoiceJour.RecId); ... только исправление на: ... FactureEditLinesCust_RU.enabled((CustInvoiceJour.RecId ? true : false)); ... ситуацию разрешило. ... аргумент должен приводиться к логическому типу Если бы ты написал CustInvoiceJour.RecId != 0 то фраза "аргумент должен приводиться к логическому типу" имела бы смысл, а так просто очевидно что это либо очередной и довольно серьезный и тонкий глюк аксапты, либо пятна на солнце. CustInvoiceJour.RecId ? true : false - это масло масляное в использованном контексте... Было бы интересно проверить эту "фичу" в своём проекте. P.S. И в свете того что я говорил в первом своём посте тут: А FactureEditLinesCust_RU.enabled( CustInvoiceJour ) не пробовали?
|
|
|
|
|
#10 |
|
Участник
|
Re: флуд
Цитата:
Вот тоже решил чуть усомниться ...
Какой компилятор может быть во время выполения?
Цитата:
...которые X++ унаследовал от C/C++ никто и никогда отменять не будет.
Да и вообще если язык программирования не может справится с чётко оговоренным преобразованием числа в булевский тип - то какая разница компилятор он или интерпретатор?
|
|
|
|
|
#11 |
|
NavAx
|
Фраза "аргумент должен приводиться к логическому типу" относится к правилу преобразования аргумента системой, но не к указанному варианту решения.
Я был тоже немало удивлен, но при этом сохранил человеческие повадки
__________________
Чудес не бывает (c), истина где-то рядом (c)... |
|
|
|
|
#12 |
|
Роман Долгополов (RDOL)
|
Цитата:
Изначально опубликовано Alks
сомневаться в этом - значит проявлять незнание языка и плодить излишне перегруженный конструкциями код ...... долго смеялся ) Вот вам джобик, запустите, а я посмеюсь ![]() PHP код:
Ну неправильно работет преобразование типов при присвоении int к boolean. В остальном все ок Так что сомневаться бывает очень полезно
|
|
|
|
|
#13 |
|
Модератор
|
Хм.. и best practise молчит насчет сравнения или проверки на наличие записи по RecId... Единственное, что нашлось:
PHP код:
![]() to db: спасибо за инфу - есть над чем задуматься... Каждое Ваше сообщение - либо дельный совет, либо куча загадок ![]() С Уважением, Георгий |
|
|
|
|
#14 |
|
Участник
|
Цитата:
Изначально опубликовано db
И пятна на солнце бывают и аксапта людьми написана. А хорошо смеется тот, кто смеется последним Вот вам джобик, запустите, а я посмеюсь ![]() PHP код:
И ведь по результатам видно что происходит какая то хрень с преобразованием отрицательных чисел кратных 256 - такое ощущение что для них перед преобразованием в boolean сперва идет преобразование в однобайтовое число. Хотел бы я узнать каким алгоритмом пользуются создатели X++ при этом преобразовании что возникает такой нехарактерный глюк. По хорошему a == true на низком уровне должно преобразовываться в a != 0, а a == false в a == 0. Как тут можно допустить исключительные ситуации с отрицательными числами ума просто не приложу! Однако, я всё таки сейчас поулыбаюсь бледной улыбкаой, сразу после предыдущего попробуйте следующий джобик: PHP код:
![]() так что if ( tbl ) вполне корректно. В подтверждение этому обратите внимание на то что участок кода: Цитата:
inventTable.(fieldnum(Common, RecId)) = -512;
if (inventTable) { print "ok"; } else { print "!!!"; } if (inventTable.RecId && 100 > 4) { print "ok"; } else { print "!!!"; } b = inventTable && 100 > 4; if (b) { print "ok"; } else { print "!!!"; } Спасибо конечно за предупреждение - теперь буду проявлять осторожность при передаче чисел как параметров в ф-ии предполагающие boolean аргумент, но глядя на то сколько сравнений вида if ( tbl ) сидит в недрах sys слоя Аксапты я свою привычку менять не буду.
|
|
|
|
|
#15 |
|
Участник
|
Цитата:
Изначально опубликовано Ser
Фраза "аргумент должен приводиться к логическому типу" относится к правилу преобразования аргумента системой, но не к указанному варианту решения. Я был тоже немало удивлен, но при этом сохранил человеческие повадки
Замечу что я не обвинял вас и не сомневался в том что такого не может быть - было просто действительно смешно видеть такие ляпы в X++. ![]() После постинга db рассеивается эта страшная тайна - передача параметра в ф-ю видимо испытывает те же трудности с конвертацией int->boolean что и явное присваивание переменной... |
|
|
|
|
#16 |
|
Участник
|
Вот еще некоторые любопытные факты из жизни конвертации чисел в boolean, немножко проливающие свет на то что находится под капотом сего глюка:
PHP код:
ВИДИМО где то в недрах интерпретатора Axapta присваивание переменной булевского типа использует следующий алгоритм конвертации (записано на языке C): byte int2bool( int i ) { return i > 255 ? 255 : i; } По вине разработчиков случай на i < 0 никак не обрабатывается, что приводит к урезанию ответа до последнего байта в этом случае и как следствие некорректному результату при i < 0 и кратных 256. |
|
|
|
|
#17 |
|
Участник
|
думаю, что все проще.
при присваивании булеву значению берется только младший байт т.е. b = i выполняется как b = lowbyte(i) |
|
|
|
|
#18 |
|
Участник
|
Цитата:
Изначально опубликовано mazzy
думаю, что все проще. при присваивании булеву значению берется только младший байт т.е. b = i выполняется как b = lowbyte(i) Преобразование real->boolean происходит по видимому еще хуже - сперва происходит преобразование real -> int с потерей дробной части (!!!) и только потом уже (по всё той же корявой схеме) из int -> boolean. Тихий ужас. Спасает только то что эти корявости имеют место быть только при присвоении к булевским переменным/параметрам ф-й, подвыражения в выражениях же вычисляются правильно. |
|
|
|
|
#19 |
|
Роман Долгополов (RDOL)
|
Похоже я всех малость напугал, уж извините, больше не буду
![]() Еще немножечко информации. Почти всю ее предыдущие авторы добыли методом тыка, просто подитожу то, что добыл когда то методом инструмента, против которого нет приема ![]() Во первых аксаптовский интерпретатор не имеет типа boolean, там есть только enum, который по совместительству используется как boolean Преобразование int->enum если int>255, то enum = 255, иначе enum=(BYTE)int соответсвенно не прокатывают все отрицательные числа, кратные -256 Преобразование dbl->int int=откинуть дробную часть(dbl) Преобразование dbl->enum int=откинуть дробную часть(dbl) enum=(BYTE)int соответственно не прокатывают все числа с откинутой дробной частью кратные как -256, так и +256 Все преобразования происходят именно так. Пришлось однажды разобраться, когда показалось, что глючит не Аксапту, а меня. В общем, наслаждайтесь. Жизнь полна неожиданностей, тем она и прекрасна
|
|
|
|
|
#20 |
|
Участник
|
Цитата:
Изначально опубликовано db
Похоже я всех малость напугал, уж извините, больше не буду
Огромное спасибо за вопросы! Побольше бы таких неожиданных и интересных. |
|
|
| Теги |
| recid, баг, ошибка, ax3.0 |
|
|
Похожие темы
|
||||
| Тема | Ответов | |||
| if (record) vs if (record.RecId) | 18 | |||
| Как сформировать RecId | 18 | |||
| поля, содержащие RecId | 15 | |||
| aEremenko: Дефрагментация RecID | 2 | |||
| Два RecId у одной записи таблицы | 33 | |||
|