On-line: гостей 0. Всего: 0 [подробнее..]
АвторСообщение
постоянный участник


Пост N: 242
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 05.12.06 12:36. Заголовок: Различие в поведении команды SAY


Вчера я обнаружил две особенности Clipper. Первая особенность связана с тем, что Clipper 5.01 не может компилировать следующее предложение

@ nRow, nCol SAY i++ PICTURE "999"

Он выдает ошибку компиляции. Если же заключить выражение i++ в скобки, то следующее предложение

@ nRow, nCol SAY (i++) PICTURE "999"

компилируется успешно. Появление ошибки связано с включением опции PICTURE в предложение. Если опцию PICTURE исключить, то предложение

@ nRow, nCol SAY i++

будет компилироваться Clipper 5.01 без ошибок.

Вторая особенность относится ко всем версиям Clipper. Команда SAY ведет себя различным образом в зависимости от того включена опция PICTURE, или нет. Если опция PICTURE включена, то команда SAY не реагирует на SCROLL BREAK (Ctrl+s) комбинацию клавишю Ежели опция PICTURE не входит в состав SAY предложения, то команда SAY реагирует паузой на нажатие комбинации клавиш для события SCROLL BREAK (Ctrl+s).
Следующая простая программа это демонстрирует.

#INCLUDE "INKEY.CH"

PROCEDURE MAIN()
LOCAL i, nKey

CLS

i := 0

DO WHILE ( ( nKey := INKEY() ) != K_ESC )
@ 10, 10 SAY ( i++ ) // PICTURE "999 999 999"
ENDDO

RETURN

Запускать программу, чтобы увидеть различие, нужно два раза: с включением PICTURE или без включения. Во время выполнения следует нажать комбинацию клавиш Ctrl+s и посмотреть, что произойдет.
На мой взгляд это - недоработка Clipper, то есть баг. Я думаю, команда SAY должна себя вести одинаково в обоих случаях. Ведь по существу мы можем предложение

@ 10, 10 SAY ( i++ ) PICTURE "999 999 999"

заменить предложением

@ 10, 10 SAY TRANSFORM( i++, "999 999 999" )

Тогда не понятно, почему такое различие в реакции на Ctrl+s должно существовать!


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 7 [только новые]


администратор




Пост N: 499
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 05.12.06 13:01. Заголовок: Re:


Версия 5.2

local nrow:=1
local ncol:=1
local i:=5
cls
@ nRow, nCol SAY i++ PICTURE "999"
wait
@ nRow, nCol SAY (i++) PICTURE "999"
wait

все пашет ;)



Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 243
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 05.12.06 13:05. Заголовок: Re:


Я специально уточнил, что этот баг связан с Clipper 5.01.
А вот вторая особенность не зависит от версии Clipper. Проверьте!

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 500
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 05.12.06 13:40. Заголовок: Re:


Григорьев Владимир пишет:

 цитата:
А вот вторая особенность не зависит от версии Clipper. Проверьте!


Да глюк , согласен !

PS
Правда ни когда я не юзал CTRL+S и мои заказчики тож. Но глюк имеет место ;)

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 244
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 05.12.06 14:07. Заголовок: Re:


Я бы сказал, что это некоторая несогласованность в интерфейсе.
Я с этим столкнулся, потому что решил написать свой класс oSay на Clipper. Что-то вроде

DEFINE SAY oSay ROW nRow COL nCol PICTURE cPicture COLOR cColor WHEN bWhen

Так как в классе как бы всегда присутствует член PICTURE (хотя он и может быть задан как NIL), возник вопрос, как реализовать метод oSay:display(). То ли иметировать полностью Clipper в зависимости от того, равняется ли oSay:picture значению NIL, или нет. То ли всегда реагировать на событие SCROLL BREAK вне зависимости от значения PICTURE. То ли всегда игнорировать событие SCROLL BREAK. Кстати сказать, метод display для класса GET, если я не ошибаюсь, полностью игнорирует событие SCROLL BREAK даже если ни один объект GET не имеет фокуса, то есть если просто GET-объекты выводятся на экран, как обычные строки.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 245
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 05.12.06 14:18. Заголовок: Re:


Правда сейчас по ходу дела пришла идея добавить в класс еще одно объявление, например MODE, которое будет принимать значения: ON, OFF, COMPATIBLE.
ON - реагировать на SCROLL BREAK в любых случаях;
OFF - игнорировать SCROLL BREAK в любых случаях;
COMPATIBLE - иммитировать поведение команды Clipper SAY в зависимости от того, чему равен член класса oSay:picture.
То есть команда объявления класса будет выглядеть следующим образом:

DEFINE SAY oSay [ROW nRow] [COL nCol] [PICTURE cPicture] [COLOR cColor] [MODE nMode]

И по умолчанию выбрать значение nMode равным OFF, то есть игнорировать SCROLL BREAK.


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 262
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 25.12.06 16:21. Заголовок: Re:


Я, наконец-то, написал свой класс SAY на Clipper. Окончательно он выглядет так

DEFINE SAY <oSay> ;
[VALUE <bValue> ] ;
[ AT <nRow> [, <nCol> ] ] ;
[ PICTURE <cPicture> ] ;
[ COLOR <cColorSpec> ];
[ WHEN <bWhen> ] ;
[ [SCROLL ] BREAK <nBreakMode: OFF, ON, STD> ]

Хотя сейчас есть сомнение: не переименовать ли VALUE в PROMPT, как это сделано в FiveWin.

Пока писал класс обнаружил еще одну несогласованность в интерфейсе класса GET (с который я использовал в качестве примера). Там аттрибут oGet:ColorSpec может задаваться либо как символьная строка, либо как логическое значение. Причем не имеет значения, какое логическое значение вы укажите: .T. или .F.. Clipper в любом случае будет использовать текущий цвет, заданный в системе на момент создания объекта или выполнения метода присвоения цвета. К тому же нельзя этот параметр "обнулить", чтобы Clipper использовал текущий цвет не в момент создания объекта, а в момент печати объекта. Поясню.

SETCOLOR( "W/N" )

oGet := GETNEW()

// теперь oGet имеет цвет "W/N"
...
SETCOLOR( "W/B" )
CLS

oGet:display()

oGet будет выводиться цветом "W/N", в то время как я хотел бы, чтобы он выводился в цвете "W/N". Поэтому для GET объекта придется делать следующее

SETCOLOR( "W/N" )

oGet := GETNEW()
// теперь oGet объект имеет цвет "W/N"
...
SETCOLOR( "W/B" )
CLS

oGet:colorSpec := SETCOLOR() // дополнительное предложение, чтобы установить нужный цвет
oGet:display()

В своем классе SAY я это исправил. Теперь если указывается логическое значение .T., то для SAY объекта устанавливается текущий цвет на момент создания объекта, либо выполнения метода oSay:colorSpec := .T.
Если же задать логическое значение .F. или NIL, то при выполнении метода
oSay:display() будет использоваться тот цвет, который является текущим на момент выполнения вывода SAY объекта. То есть это как бы отложенное задание цвета до момента вывода SAY объекта.
Когда писал свой класс, то меня заинтересовало, а как быстро будет выврдиться SAY-объект по сравнению с обычной командой SAY. Наверное никто ранее такой проверки не делал. Из нее видно, как выполнение обычной команды SAY (и моего класса SAY) меняется в зависимости от того, указывается ли кодовый блок для переменной, указывается ли параметр PICTURE. Мой класс работает помедленней, но не значительно. А вот отдельное выполнение метода oSay:value := i++ занимает много времени, что показывает первый тест.
Тестовую программу и ее исходный код можно скачать отсюда:

выполнимый модуль
исходный код

Некоторые замечания о нашем тяжелом труде программиста!
Напимсание класса у меня заняло 10 дней. Самый сложный метод oSay:display() я писал два выходных дня (субботу и воскресенье), не вылазия из дома. При этом уже кое что для этого метода было "наброшено" в будни. При этом я знал, что пистаь, то есть дизайн класса для меня был прозрачен, то есть время уходило на техническую работу. Итак, в лучшем случае (на самом деле в идеальном случае) программист может за месяц написать два класса. Но это идеальный случай. Некоторые классы порой значительно сложнее, чем SAY класс. Более того не всегда с самого начала ясен дизайн класса. Иногда плохо представляешь, как должен работать класс, и как его технически реализовать. Выходит, что один программист в год может написать в лучшем случае где-то 15 классов. То есть это время, затраченное только на написание самих классов. А ведь требуется еще время на адаптацию классов в своей прикладной программе! Так что немного мы можем сделать за свою программисткую карьеру! Более того, к сожалению не всякая работа программиста имеет выход к пользователю, чтобы получить за это деньги. Так написание класса никто, кроме тебя самого оценить не сможет.


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 263
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 25.12.06 17:28. Заголовок: Re:


Еще интересную вещь обнаружил, когда запускал свой тест для SAY команды и соответствующего класса. Как я уже говорил ранее, если SAY команда содержит опцию PICTURE, то комбинация клавиш CTRL+S (Scroll Break) игнорируется. В своем классе я установил три режима для реакции на CTRL+BREAK:
OFF - нажатие CTRL+S полностью игнорируется
ON - нажатие на CTRL+S всегда обрабатывается не зависимо от того, задана ли опции PICTURE, или нет.
STD - нажатие CTRL+S обрабатывается точно также, как для команды Clipper SAY, то есть если опция PICTURE не задана, то CTRL+S обрабатывается, иначе нет.

Так вот, в своем третьем тесте, где задана опция PICTURE (это означает, что нажатия CTRL+S будут игнорироваться) если я нажимаю CTRL+S, то тест выполняется быстрее!
Я получил следующие результаты:

Без нажатия CTRL+S

nEnd1 = 1.93; nEnd2 = 2.19

С нажатием CTRL+S

nEnd1 = 1.75; nEnd2 = 2.09

Странный результат!

Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 17
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет