20.08.2004, 15:53 | #1 |
Участник
|
Проверка на RecId
Привет.
Возник следующий вопрос: Есть код: Table1 table1 = Table1::find(_Key); далее проверка, которую можно выполнить двумя способами ; if (table1) { ..... } и if(table1.recId) { ... } Является ли первый способ корректным? |
|
20.08.2004, 16:09 | #2 |
Участник
|
в первом, насколько я понимаю, способе происходит неявное преобразование типов.
при преобразовании Common -> Int, Аксапта самостоятельно подставляет recID. Поэтому, сейчас технически работают оба способа. Рекомендуется использовать второй. (Рекомендацию видел где-то в презентациях, где точно уже не помню) |
|
20.08.2004, 16:32 | #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 |
|
20.08.2004, 16:51 | #4 |
Участник
|
Цитата:
Изначально опубликовано Maxim Gorbunov
Только не Common в int, а Common в boolean. |
|
22.08.2004, 06:32 | #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 ) Хотя в принципе всё это вопрос вкуса и относится к той же теме что и вопрос о том звёздочками или плюсиками лучше помечать блоки комментариев в коде. |
|
23.08.2004, 09:52 | #6 |
----------------
|
Проверка If(table) более интеллектуальна, чем проверка If(table.RecID).
Например, после агрегации и ограничения списка выбираемых полей возможна ситуация, когда RecId = 0, но If(table) = true Для проверки после find, действительно, нет разницы как проверять наличие результата. |
|
23.08.2004, 10:14 | #7 |
NavAx
|
уже довольно давно правил такой код на форме накладных:
PHP код:
только исправление на: PHP код:
Это конечно же не конструкция if, но все равно аргумент должен приводиться к логическому типу
__________________
Чудес не бывает (c), истина где-то рядом (c)... |
|
23.08.2004, 10:18 | #8 |
Участник
|
флуд
Цитата:
Чётко и ясно сказано что нулевое значение аргумента воспринимается компилятором как false, а ненулевое - true, сомневаться в этом - значит проявлять незнание языка и плодить излишне перегруженный конструкциями код.
Какой компилятор может быть во время выполения?
__________________
Уточните значение слов и вы избавите человечество от половины его заблуждений. (Рене Декарт) / Axapta 2.5 |
|
23.08.2004, 12:31 | #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 ) не пробовали? |
|
23.08.2004, 12:41 | #10 |
Участник
|
Re: флуд
Цитата:
Вот тоже решил чуть усомниться ...
Какой компилятор может быть во время выполения? Цитата:
...которые X++ унаследовал от C/C++ никто и никогда отменять не будет.
Да и вообще если язык программирования не может справится с чётко оговоренным преобразованием числа в булевский тип - то какая разница компилятор он или интерпретатор? |
|
23.08.2004, 15:36 | #11 |
NavAx
|
Фраза "аргумент должен приводиться к логическому типу" относится к правилу преобразования аргумента системой, но не к указанному варианту решения.
Я был тоже немало удивлен, но при этом сохранил человеческие повадки
__________________
Чудес не бывает (c), истина где-то рядом (c)... |
|
23.08.2004, 16:09 | #12 |
Роман Долгополов (RDOL)
|
Цитата:
Изначально опубликовано Alks
сомневаться в этом - значит проявлять незнание языка и плодить излишне перегруженный конструкциями код ...... долго смеялся ) PHP код:
Ну неправильно работет преобразование типов при присвоении int к boolean. В остальном все ок Так что сомневаться бывает очень полезно |
|
23.08.2004, 16:49 | #13 |
Модератор
|
Хм.. и best practise молчит насчет сравнения или проверки на наличие записи по RecId... Единственное, что нашлось:
PHP код:
to db: спасибо за инфу - есть над чем задуматься... Каждое Ваше сообщение - либо дельный совет, либо куча загадок С Уважением, Георгий |
|
24.08.2004, 05:53 | #14 |
Участник
|
Цитата:
Изначально опубликовано db
И пятна на солнце бывают и аксапта людьми написана. А хорошо смеется тот, кто смеется последним Вот вам джобик, запустите, а я посмеюсь PHP код:
Однако, я всё таки сейчас поулыбаюсь бледной улыбкаой, сразу после предыдущего попробуйте следующий джобик: 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 "!!!"; } |
|
24.08.2004, 06:19 | #15 |
Участник
|
Цитата:
Изначально опубликовано Ser
Фраза "аргумент должен приводиться к логическому типу" относится к правилу преобразования аргумента системой, но не к указанному варианту решения. Я был тоже немало удивлен, но при этом сохранил человеческие повадки После постинга db рассеивается эта страшная тайна - передача параметра в ф-ю видимо испытывает те же трудности с конвертацией int->boolean что и явное присваивание переменной... |
|
24.08.2004, 11:14 | #16 |
Участник
|
Вот еще некоторые любопытные факты из жизни конвертации чисел в boolean, немножко проливающие свет на то что находится под капотом сего глюка:
PHP код:
ВИДИМО где то в недрах интерпретатора Axapta присваивание переменной булевского типа использует следующий алгоритм конвертации (записано на языке C): byte int2bool( int i ) { return i > 255 ? 255 : i; } По вине разработчиков случай на i < 0 никак не обрабатывается, что приводит к урезанию ответа до последнего байта в этом случае и как следствие некорректному результату при i < 0 и кратных 256. |
|
24.08.2004, 12:00 | #17 |
Участник
|
думаю, что все проще.
при присваивании булеву значению берется только младший байт т.е. b = i выполняется как b = lowbyte(i) |
|
24.08.2004, 12:22 | #18 |
Участник
|
Цитата:
Изначально опубликовано mazzy
думаю, что все проще. при присваивании булеву значению берется только младший байт т.е. b = i выполняется как b = lowbyte(i) Преобразование real->boolean происходит по видимому еще хуже - сперва происходит преобразование real -> int с потерей дробной части (!!!) и только потом уже (по всё той же корявой схеме) из int -> boolean. Тихий ужас. Спасает только то что эти корявости имеют место быть только при присвоении к булевским переменным/параметрам ф-й, подвыражения в выражениях же вычисляются правильно. |
|
24.08.2004, 14:52 | #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 Все преобразования происходят именно так. Пришлось однажды разобраться, когда показалось, что глючит не Аксапту, а меня. В общем, наслаждайтесь. Жизнь полна неожиданностей, тем она и прекрасна |
|
24.08.2004, 15:28 | #20 |
Участник
|
Цитата:
Изначально опубликовано db
Похоже я всех малость напугал, уж извините, больше не буду Огромное спасибо за вопросы! Побольше бы таких неожиданных и интересных. |
|
Теги |
recid, баг, ошибка, ax3.0 |
|
Похожие темы | ||||
Тема | Ответов | |||
if (record) vs if (record.RecId) | 18 | |||
Как сформировать RecId | 18 | |||
поля, содержащие RecId | 15 | |||
aEremenko: Дефрагментация RecID | 2 | |||
Два RecId у одной записи таблицы | 33 |
|