:: Visual Foxpro, Foxpro for DOS
Re: Как добавить метод к пользовательскому объекту
lulgu

Сообщений: 1838
Дата регистрации: 30.11.2016
of63
Берешь и пишешь в Click кнопки
LPARAMETERS m.par1
IF PCOUNT()=0 && штатный обработчик Click
...
ELSE && нештатный код, выполняется при "нелегальном" вызове: ThisForm.кнопка.Click(1)
...
ENDIF

А зачем это нужно?
Ratings: 0 negative/0 positive
Re: Как добавить метод к пользовательскому объекту
of63

Сообщений: 25161
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Если не было необходимости "добавить метод к имеющемуся обьекту", то значит это было не нужно.
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
Berloga

Сообщений: 72
Откуда: Нефтекамск
Дата регистрации: 19.12.2007
Crispy
Единственное, что к сожалению не сделано в Фоксе - нельзя добавлять свои методы к объектам формы.
Можно поменять класс формы на свой класс из своей библиотеки с помощью Redefine в Class Browser, предварительно нажав на кнопку View Additional File. И далее работать с формой как с формой, но при этом на форме свои фичи. Вполне легальное действие.
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
of63
Обьекты, с методами - это замечательно, за исключением одной "маленькой" заковыки: при написании кода метода нельзя применять подпрограммы, годящиеся исключительно для этого метода. Приходится создавать дополнительные ничтожные "методы", или выносить код в те же ПРГшки, если код большой. А в остальном ... все хорошо.
Никакой "заковыки". Если нужны "маленькие методы", значит нужен не один мега-модуль "с подпрограммами", а нужен КЛАСС с этими самыми методами. И этот класс и будет использоваться в соответствующем "коде метода".
Не нужно смешивать 100500 классов в один, чтобы потом мучиться с огромной простынёй этих самых "мелких методов".
Декомпозиция позволяет сделать всё просто, красиво и удобно.
prg как хранилища миллионов процедур не нужны. Равно как и сами эти миллионы процедур.

Единственное неудобство в фоксе, это именно необходимость создавать экземпляр класса чтобы вызвать его метод. Т.е. "лишняя" строка кода
oSome = CreateObject("MyClass")

Впрочем, это всё вопрос понимания принципа и привычки. Не уверен что можно слепого убедить в прелестях кинематографа - ему и радио вполне достаточно


------------------
WBR, Igor
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
lulgu

Сообщений: 1838
Дата регистрации: 30.11.2016
of63
Если не было необходимости "добавить метод к имеющемуся обьекту", то значит это было не нужно.

Честно говоря, я тоже не понимаю, для чего это.
Например, проще добавить на форму новый метод, скажем DoUtil(), и пиши в нем через DO CASE хоть вагон методов безо всяких заморочек.
Этот прием годится также для всяких "мелких" подпрограмм.



Исправлено 1 раз(а). Последнее : lulgu, 27.04.17 16:08
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
of63

Сообщений: 25161
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
> не один мега-модуль "с подпрограммами", а нужен КЛАСС с этими самыми методами
Не нужны мне эти методы ни в классе ни в обьекте, их много, и они того не стОят. Может стиль такой у меня программирования - "все осмысленные кода куски размером не более одного экрана". Надо что-то типа "подпрограмма в подпрограмме", LOCAL-подпрограмма. Ну, нет и нет, лепим из того, что есть.

> Единственное неудобство в фоксе, это именно необходимость создавать экземпляр класса чтобы вызвать его метод.
> Т.е. "лишняя" строка кода oSome = CreateObject("MyClass")
Напиши подпрограмму в "фреймверке":

FUNCTION classFunction(className, classMethod, ...)
LOCAL m.o
m.o = CreateObject(className)
RETURN m.o.&classMethod()
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Berloga
Можно поменять класс формы на свой класс из своей библиотеки с помощью Redefine в Class Browser, предварительно нажав на кнопку View Additional File
На самом деле там всё ОЧЕНЬ непросто будет, по причине того что форма это контейнер, и между объектами накиданными на форму в редакторе форм (тех что прописаны в scx) и объектами накиданными на форму в дизайнере классов (тех что в vcx были, и "автоматом" переезжают на все формы унаследованные от этого класса) может возникнуть нехилый конфликт.
Даже просто между методами и свойствами которые добавлены в класс и в scx может не совсем желательное пересечение получиться (тривиально - "универсальный" Resize из класса формы не работает, т.к. в Resize конечной формы был прописан код но не было вызова DODEFAULT), а уж с объектами и того хуже. Если на форме есть кнопка cmdClose и если в классе на который мы делаем "подмену" тоже есть кнопка с таким именем, то в итоге получим очень нехорошую ситуацию... Элемента на форме будет два, у них будет идентичное имя, и, соответственно, программный доступ к одному из них (тому что был в классе описан) внезапно станет направлять на совсем другой элемент (тот что на форме описан).

И уж совсем беда будет если менять не "базовый" класс form на свой, а один класс формы на другой - там напротив могут "пропасть" какие-то элементы с формы, которым был прописан код...
Ещё хуже если делать redefine не scx форме, а промежуточному классу. Т.е. менять иерархию наследования. Там эти конфликты могут вообще крайне плачевно закончиться.

В общем redefine нужно очень и очень аккуратно использовать. Равно как и правку базовых классов (неважно формы, или контейнера с элементами) когда эти классы уже вовсю используются в проекте. Любое такое изменение (особенно если оно связано с добавлением/удалением вложенного элемента) нужно тщательно проверять - не поломает ли оно те классы/формы где данный класс был задействован.


------------------
WBR, Igor
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
of63

Сообщений: 25161
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
> Например, проще добавить на форму новый метод, скажем DoUtil(), и пиши в нем через DO CASE хоть вагон методов безо всяких заморочек.

Конечно, есть куча мест где разместить код, от SET PROCEDURE до "в классе". Но вот житейский пример:
- на форме куча однотипных кнопок
- перебираем кнопки на форме FOR..ENFOR и раскрашиваем их по известному принципу
- приспичило на одной-двух кнопках при покраске выполнить произвольный код, пусть например, этот код наполняет ToolTipText каким-то текстом, который известен только в момент обхода, и выполняет сложные подпрограммы фреймверка. Решение - разместим метод "спецдействия" на каждой кнопке. Как добавить метод? Конечно, создав класс "кнопкаСспецдействием". Но можно и без класса, разместив этот кол в нативной кнопке, в штатном методе Click. Обходчик будет на каждой кнопке вызывать метод кнопка.Click(1), в нужной кнопке напишем вышеуказанный код с PCOUNT(). Мы сэкономили один класс, который может нужен нам был только на единственной форме. К тому же код лежит прямо в кнопке! Это удобно.

Конечно, можно это решить и добавлением Property на кнопке с именем метода на форме например, этому методу обходчик будет передавать "указатель" на кнопку... Но можно и через ж так.
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
of63
Может стиль такой у меня программирования
Вероятно.
of63
"все осмысленные кода куски размером не более одного экрана"
Именно этот принцип ну НИКАК не противоречит ООП подходу. Даже очень поощряется там, т.к. сам ООП и есть подход декомпозиции "сложного и объёмного" на "небольшие и удобные" части.
of63
Надо что-то типа "подпрограмма в подпрограмме", LOCAL-подпрограмма.
Как по мне, так такое требуется весьма нечасто. Даже в активно развивающемся C# такая штука появилась лишь сейчас в 7-й версии стандарта языка!
И "по сути" она есть синтаксический сахар над самым обычным "ещё одним мелким скрытым методом в классе". Грубо говоря избавились от строчек PROCEDURE ... ENDPROC, и сам "текст" перенесли внутрь кода другого метода (что имеет как плюсы так и минусы, т.к. сам то метод из-за этого раздувается).
of63
Напиши подпрограмму в "фреймверке"
Не вижу надобности в таком корявом костыле Даже если бы продолжал что-то на фоксе делать, то проще такие приёмы обойти по другому (банально в goApp завести свойство или даже целую коллекцию - хотя доступ через коллекцию заметно медленнее будет - где и хранить ссылки на такого рода "статические классы"), нежели грузить и так небыстрый интерпретатор вызовом функции, созданием экземпляра, вызовом метода через макро... Тем более что самую мякотку, т.е. "прозрачную" передачу параметров через эту функцию-обёртку (коих неизвестно сколько нужно! может ни одного, может 5 а может и все 20 - так что там ещё пару строк кода и ещё одно макро нужно) ты скромно "умолчал"


------------------
WBR, Igor
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
lulgu

Сообщений: 1838
Дата регистрации: 30.11.2016
of63
> Например, проще добавить на форму новый метод, скажем DoUtil(), и пиши в нем через DO CASE хоть вагон методов безо всяких заморочек.
Конечно, есть куча мест где разместить код, от SET PROCEDURE до "в классе". Но вот житейский пример:
- на форме куча однотипных кнопок
- перебираем кнопки на форме FOR..ENFOR и раскрашиваем их по известному принципу
- приспичило на одной-двух кнопках при покраске выполнить произвольный код, пусть например, этот код наполняет ToolTipText каким-то текстом, который известен только в момент обхода, и выполняет сложные подпрограммы фреймверка. Решение - разместим метод "спецдействия" на каждой кнопке. Как добавить метод? Конечно, создав класс "кнопкаСспецдействием". Но можно и без класса, разместив этот кол в нативной кнопке, в штатном методе Click. Обходчик будет на каждой кнопке вызывать метод кнопка.Click(1), в нужной кнопке напишем вышеуказанный код с PCOUNT(). Мы сэкономили один класс, который может нужен нам был только на единственной форме. К тому же код лежит прямо в кнопке! Это удобно.

Конечно, можно это решить и добавлением Property на кнопке с именем метода на форме например, этому методу обходчик будет передавать "указатель" на кнопку... Но можно и через ж так.

Да не надо никаких классов и выкрутасов.
Скажем, ваша функция func1.
Создаете func1ex и в ней пишете:

LPARAMETERS tcCase,tuParam1,tuParam2 ...
DO CASE
CASE tcCase == 'Кнопка1'
*код
CASE tcCase == 'Кнопка2'
*код
...
ENDCASE
Я бы вообще все разместил в той же процедуре func1:
LPARAMETERS tcCase,tcTema,tuParam1,tuParam2 ...
DO CASE
CASE tcCase == 'Func1'
*код
CASE tcCase == 'Func1ex'
DO CASE
CASE tcTema == 'Кнопка1'
*код
CASE tcTema == 'Кнопка2'
*код
...
ENDCASE
ENDCASE



Исправлено 1 раз(а). Последнее : lulgu, 27.04.17 16:54
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
of63
Решение - разместим метод "спецдействия" на каждой кнопке. Как добавить метод? Конечно, создав класс "кнопкаСспецдействием".
И это разумно. При том в классе можно описать "стандартное" поведение (если таковое имеется), а на самой форме, для пары кнопок переписать это "стандартное" на своё "особо хитрое".
Это логично, понятно и достаточно красиво.
of63
Но можно и без класса, разместив этот кол в нативной кнопке, в штатном методе Click.
А смысл? Чтобы тот кто потом будет читать код долго чесал репу - а нах там стоит Click(1), никаких параметров метод не принимает, что за хрень? А почему не Click(2)?
И ещё веселее если это будет прописано в классе. На одном уровне иерархии наследования click(1) будет означать "заполнить ToolTiptext таким-то макаром", на другом click(1) будет выполнять "изменить размер кнопки в соответствии с этаким то алгоритмом", а потом ещё и на самой форме Click(1) будет заниматься "скрытием кнопки по пятницам"
Это в чистом виде г*нокод.
Неочевидно, запутано и нелогично. При том ещё зачастую и не работает как предполагалось

of63
Мы сэкономили один класс
С какой целью?
Почему же ты тогда не "экономишь процедуры", прописывая весь код программы в одной мега-процедуре - простыне на 100500 строк кода Зачем чего-то "вызывать", если проще прямо тут, по месту эти 5-10-30 строк кода написать И ничего что через 5 страниц потребуются те же строки кода - но там же уже не
FOR i123 = 1 TO 12
? i123, "приход", csr15.z987
? "---"
? "остаток", csr15.z654
SKIP
ENDFOR
будет, а
FOR j584 = 1 TO 12
? j584, "приход", csr37.z987
? "---"
? "остаток", csr37.z654
SKIP
ENDFOR
Это ж "совсем меняет дело"


------------------
WBR, Igor
Ratings: 0 negative/2 positive
Re: Как добавить метод к пользовательскому объекту
of63

Сообщений: 25161
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Игорь, эпитеты опустил, осталось:

> Напиши подпрограмму в "фреймверке"
> Ответ: ...в goApp завести свойство где и хранить ссылки на такого рода "статические классы"
Я так понял, при старте программы например, заранее создать CREATEOBJECT("MyClass"), потом обращаться по этой ссылке для выполнения метода "MyFunc" ? Если не заморачиваться с именованием свойства в goApp, и заранее знать имя ссылки, то макрос не потребуется, иначе придется делать
=ADDPROPERTY(goApp, "staticMyClass", CREATEOBJECT("MyClass"))
причем далее заранее знать, что имя ее - "staticMyClass". Если же не знать, то или макрос, или массив [имя_класса, обьект_этого_класса] и ASCAN, в простейшем случае создавать ссылку с именем, совпадающим с именем класса. Все это какие-то дополнительные телодвижения, "ограничения".
Все это хорошо в "школьном" примере изготовления обьекта с набором функций, например, типа работы с строками:
goApp.CHRTRANex()
goApp.STRTRANex()
...

> ...и "прозрачную" передачу параметров через эту функцию-обёртку...ты скромно "умолчал"
Я сама скромность. В сложной программе все время что-то нужно "встроить" в процесс вызова goApp.STRTRANex, приходится оборачивать в подпрограмму, потом и ее, и еще раз...в этом случае "прозрачная" передача параметров превращается в макрос - список имен параметров... Бывает, что другого пути нет, не переписывать же тонну классов, если что-то надо встроить в процедуру их использования. Ничего страшного в этом не вижу. Надо, значит надо.
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
of63

Сообщений: 25161
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
> Да не надо никаких классов и выкрутасов.
> Скажем, ваша функция func1.
> Создаете func1ex и в ней пишете:


LPARAMETERS tcCase,tuParam1,tuParam2 ...
DO CASE
CASE tcCase == 'Кнопка1'
*код
CASE tcCase == 'Кнопка2'
*код
...
ENDCASE

Да, можно хоть весь свой фреймерк выполнить в виде кода с CASE tcCase="MuFunc1" ... моя функция 1... и так 100-1000 раз.
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
lulgu

Сообщений: 1838
Дата регистрации: 30.11.2016
of63
> Да не надо никаких классов и выкрутасов.
> Скажем, ваша функция func1.
> Создаете func1ex и в ней пишете:


LPARAMETERS tcCase,tuParam1,tuParam2 ...
DO CASE
CASE tcCase == 'Кнопка1'
*код
CASE tcCase == 'Кнопка2'
*код
...
ENDCASE

Да, можно хоть весь свой фреймерк выполнить в виде кода с CASE tcCase="MuFunc1" ... моя функция 1... и так 100-1000 раз.
Да, можно. Но в этом нет никакой необходимости, оптимальный результат достигается за счет тематической компоновки.
Также нет необходимости завязывать goApp с какими-либо классами или процедурами.
Создайте еще пару глобальных классов Container, куда и добавляйте свои классы, этого достаточно.
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
of63
Если не заморачиваться с именованием свойства в goApp, и заранее знать имя ссылки
Конечно же заранее. И, конечно, никаких макро не нужно.
Код должен быть строгим. В типизированном языке вообще ОЧЕНЬ строгим. Вызывать непойми что непойми где расположенное - это самый что ни на сеть "эпитет".
of63
Все это какие-то дополнительные телодвижения, "ограничения".
Нет, это называется другим словом. Порядок. В противовес бардаку
of63
В сложной программе все время что-то нужно "встроить" в процесс вызова
Зачем?
Почему вот мне, к примеру, никогда не требовалось и не требуется чего-то куда-то "встроить" чтобы поменять штатное поведение какого-то метода или, если про фокс говорить, какой-то функции?

Вызвать нечто ДРУГОЕ, которое делает "и то и это и пятое и десятое" - это да, это надо. Но это ж всегда ЯВНО прописывается. Я вызываю функцию, к примеру, отсеивания из строки всех символов кроме русских букв и цифр. Или функцию перевода числа "в строку прописью" на русском языке в указанном склонении. И мне не требуется "на лету" менять поведение этих статически/неизменно/железобетонно написанных функций так, чтобы первая "заодно" отбрасывала буквы Ё и Ъ, а вторая, к примеру, добавляла после каждого слова "неопределённый артикль бл*". Это нелогично -> это неправильно и это в чистом виде "эпитет"
Ровно то же самое (т.е. применить "эпитет") я могу сказать и про Click(1) для вызова "какого-то там произвольного кода", и про Proc("действие", "ещё действие", параметр_непойми_чего1, параметр_непойми_чего2, ...) чтобы через одну и ту же "процедуру" вызывать 100500 разнообразных "поведений" - через CASE на 50 страниц кода, или ещё как. И про игнорирование принципов ООП в системах являющихся объектно-ориентированными (писать в VFP используя подход FPD)...


------------------
WBR, Igor
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
of63

Сообщений: 25161
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Почему ты CASE упомянул, это я для lulgu писал )

Нет, без ООП (без "рыбы" обьекта, без иерархии, без "наследуй класс и допили в процессе исполнения") я уже не могу, в FPD ничего такого уже не получится. VFP стал "событийным", т.е. например, "пишем код код, который будет выполнен, если нажмут кнопка.Click", все выполняется в одной фоксовой строке - READ EVENTS. Это прогресс для FPD, к тому же с некоторой совместимостью перехода. Все хорошо.

> Код должен быть строгим
Ну... код должен быть рабочим. И покороче, и с комментариями (обьемом в разы > кода) на всякий случай, для самого же разраба. А строгим, или распутным получается код, у кого какой, код - это как ребенок.

> И, конечно, никаких макро не нужно
Если язык предоставляет макро, то значит он нужен, например, для упрощения же кода. Например, можно многоэтажный SELECT свести к символике например, блок
SELECT * FROM ddd WHERE id IN (SELECT ааа FROM bbb WHERE ccc) превратить в:
w = "SELECT id FROM bbb WHERE ccc" && получаем список клиентов
SELECT * FROM ddd WHERE id IN (&w) && извлекаем данные о клиентах
Послать запрос на SQL-сервер - тоже такой же "макрос", никто же кричит, "долой символьную строку, даешь обьектную модель запроса"
Злоупотребить можно конечно макросом, но критерий работоспособность остается важным. Сопроводимость - дело разраба, или д.б. прописано в ТЗ, чтобы "и кухарка могла сопровождать". Заказчик смотрит на контору обычно (или на самого разраба), сам сопровождать он ничего не собирается. Программы без разраба умирают, и переписываются заново.



Исправлено 2 раз(а). Последнее : of63, 27.04.17 19:02
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
of63
Почему ты CASE упомянул, это я для lulgu писал )
Какая разница - IF в Click из той же оперы. Тут клик, а тут абы что.
of63
Ну... код должен быть рабочим. И покороче, и с комментариями (обьемом в разы > кода) на всякий случай, для самого же разраба.
Вот тебе "рабочий" код:
DO WHILE .T.
? "Я работаю, не мешай"
ENDDO
В то же время бессмысленный и даже вредный...
Комментарии нужны для уточнения неочевидных мест. В идеале таких мест не должно быть вообще (т.е. идеальная программа такова, что понимается вообще БЕЗ комментариев - прямо по коду).
Если 90% кода это комментарии, то либо вместо программиста работал писатель (живописуя и так очевидные вещи), либо код настолько ущербный что без поллитра (или даже дозы герыча) его не понять даже с комментариями
of63
> И, конечно, никаких макро не нужно
Если язык предоставляет макро, то значит он нужен
Речь про конкретно данный случай, а не "вообще".
of63
критерий работоспособность остается важным.
Нет, нам не нужна победа любой ценой


------------------
WBR, Igor
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
of63

Сообщений: 25161
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Да... Типа: ребенок должен быть отличником, начитанным, высоким, спортсменом, без в/п, дружить с девочкой и хорошей семьи, и все, чего он добьется, то только честным трудом... Как-то так, конечно должно быть.
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
akvvohinc

Сообщений: 4201
Откуда: Москва
Дата регистрации: 11.11.2008
of63
> одноименные c фреймфорком (Ф) функции из prg1 будут иметь более высокий приоритет
мне так и надо
Как-то это не стыкуется с первоначальной посылкой, что SET PROC TO prg1 ADDI ты не пользуешься как раз потому, что одноименные функции из prg1 станут на время "главнее" фреймворковских. Ну, так и при DO func1 IN prg1 происходит похожее, но в этом случае "тебе так и надо".
Ratings: 0 negative/1 positive
Re: Как добавить метод к пользовательскому объекту
of63

Сообщений: 25161
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
SET PROC TO prg1 ADDI испортит Ф своими ф-иями, точнее, может испортить (смотря какую ф-ию фокс найдет первее)

При при DO func1 IN prg1 происходит НЕ похожее (гарантированно первее будут использованы внутренние ф-ии prg1), но в этом случае "тебе так и надо".
Ratings: 0 negative/1 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 17 (Гостей: 17)

© 2000-2024 Fox Club 
Яндекс.Метрика