:: Visual Foxpro, Foxpro for DOS
Re: Функция проверки существования переменной
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
Я понял о чем речь)
akvvohinc
- во-вторых, в скорее, во-первых - как ты определишь, в каких случаях надо добавить этот новый аргумент при вызове функции? Ведь эта функция вызывается иначе не обязательно в той процедуре, в которой он определял переменную, а из любой процедуры, лежащей ниже в стеке вызовов:
1) Из процедуры C вызывается функция F.
2) При этом, если C вызывается из процедуры A (не обязательно напрямую), то функция F должна отработать иначе, чем когда C вызвана, минуя А.
В этом случае, такой подход для отладки - самое оно)
Главное после отладки, не забыть, сделать нормально. Не забыть про этот костыль.
Иначе... через короткое время, при возвращении, к той же проблеме, неминуемые длительные поиски, разборки своего кода.
Надо стараться уменьшать зависимости.
По любому, длительная приват видимость (про паблик молчу, оставим эту лулгам) не есть хорошо.


------------------
Ratings: 0 negative/0 positive
Re: Функция проверки существования переменной
lulgu

Сообщений: 1838
Дата регистрации: 30.11.2016
Аспид
По любому, длительная приват видимость (про паблик молчу, оставим эту лулгам) не есть хорошо.

Еще раз, лично для вас, из хелпа:

Команда PRIVATE
Скрывает определенные переменные или массивы, которые были определены в вызываемой программе из текущей программы.

Просто не забывайте вовремя объявлять LOCAL-переменные и все у вас получится, даже через полгода.
А с PUBLIC-переменными что у вас за проблемы, раз вы "молчу"?



Исправлено 2 раз(а). Последнее : lulgu, 27.04.18 12:30
Ratings: 2 negative/0 positive
Re: Функция проверки существования переменной
akvvohinc
Автор

Сообщений: 4212
Откуда: Москва
Дата регистрации: 11.11.2008
lulgu
Чтобы избежать трудных имен переменных, можно использовать такую конструкцию:

LOCAL puParam1
PRIVATE puParam1
? функция()
и переменная исчезнет сама.

1) Что бы там ни было написано в Help, LOCAL-переменная не будет скрыта командой PRIVATE.
2) Да и смысл скрывать LOCAL-переменную от функции, в которой ее и так не видно?



Исправлено 1 раз(а). Последнее : akvvohinc, 27.04.18 19:03
Ratings: 0 negative/2 positive
Re: Функция проверки существования переменной
akvvohinc
Автор

Сообщений: 4212
Откуда: Москва
Дата регистрации: 11.11.2008
lulgu
Команда PRIVATE
Скрывает определенные переменные или массивы, которые были определены в вызываемой программе из текущей программы.

Перевод неверный.
Ratings: 0 negative/1 positive
Re: Функция проверки существования переменной
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Аспид
ИМХО. Чем плохо. Через пол года, снова надо будет вызвать эту функцию с этим параметром. Замучаешься имя искать))) Скорее новое создашь, и еще одну вставку сделаешь)
Плохо оно не тем что "сложно искать", а тем что поведение зависит от совершенно "левого", постороннего фактора. При том в этом случае на самом деле во ВСЕХ 100500 точках вызова функции потребуется писать либо
RELEASE lksdljhsfhgdfkjhskdfj
либо
PRIVATE lksdljhsfhgdfkjhskdfj
либо
lksdljhsfhgdfkjhskdfj = ...
в зависимости от того надо нам "старое" (первые 2 варианта) либо "новое" поведение. Хорошенькое такое "упрощение".
Конечно же писать RELEASE/PRIVATE не обязательно - но тогда зависеть выбор ветки будет вообще от неизвестно чего - т.к. вызывающий код никак не контролирует наличие private переменной. Именно по этой причине всех любителей private следует бить по голове до просветления (есть лишь несколько ОЧЕНЬ специфических случаев когда использование private оправдано. Передача такого рода "параметров/флагов" в свою собственную функцию к этим случаям не относится).

В то время как введение необязательного параметра потребует внесения модификаций только в те вызовы функции, где потребуется "новое поведение" - старый код остаётся абсолютно неизменным.

Аспид
Хотя решается все элементарно. Добавляешь еще параметр, и проверяешь его существование.
Да, только проверять его "передачу/не передачу" следует через PCOUNT(), а TYPE использовать для контроля типа, а не для определения "факта наличия" - тем более что для параметров соответствующий идентификатор инициализируется всегда (грубо говоря переменная "новый_параметр" будет создана всегда - только тип её будет "L" если она не передана из точки вызова).

akvvohinc
- во-первых, править придется все 100500 вызовов функции, где это требуется;
Конечно же нет. Старый код остаётся неизменным, только новый, где и нужна "новая ветвь" потребует указания дополнительного параметра.
CLEAR
? test(10,20)
? test(30,40)
? test(10,20,20)
? test(30,40,70)
FUNCTION test
LPARAMETERS tnParam1, tnParam2, tnBribePercent
IF PCOUNT() < 3
? "Old version"
RETURN m.tnParam1+m.tnParam2
ELSE
? "New version"
RETURN (m.tnParam1+m.tnParam2)*(1+m.tnBribePercent/100)
ENDIF

akvvohinc
Ведь эта функция вызывается иначе не обязательно в той процедуре, в которой он определял переменную, а из любой процедуры, лежащей ниже в стеке вызовов
Для чего такое может понадобиться? Может быть "в консерватории" надо кой чего поправить, а не лячкать г*нокод
Скажем для изолирования "набора процедур" придуманы классы, и в них свойства - как общее для данного набора кода "состояние" и общие же "данные".
За использование такого рода неочевидных и неотслеживаемых взаимосвязей ещё 20 лет назад надо было нещадно бить. Сегодня же вообще без разговоров такого "разработчика" на улицу выставлять надо
Код должен быть простым, абсолютно предсказуемым и легко читаемым.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Функция проверки существования переменной
lulgu

Сообщений: 1838
Дата регистрации: 30.11.2016
...



Исправлено 1 раз(а). Последнее : lulgu, 27.04.18 19:38
Ratings: 0 negative/0 positive
Re: Функция проверки существования переменной
lulgu

Сообщений: 1838
Дата регистрации: 30.11.2016
lulgu
akvvohinc
lulgu
Чтобы избежать трудных имен переменных, можно использовать такую конструкцию:

LOCAL puParam1
PRIVATE puParam1
? функция()
и переменная исчезнет сама.

1) Что бы там ни было написано в Help, LOCAL-переменная не будет скрыта командой PRIVATE.
2) Да и смысл скрывать LOCAL-переменную от функции, в которой ее и так не видно?

Вы как всегда правы:
? функция() && .F.
puParam = 0
? функция() && .T.
FUNCTION функция
RETURN VARTYPE(puParam) != "U"

RS. Попутно надо признать, что даже замечания от самого ИК не умаляют находку от of63.
Ratings: 2 negative/0 positive
Re: Функция проверки существования переменной
lulgu

Сообщений: 1838
Дата регистрации: 30.11.2016
Igor Korolyov
CLEAR
? test(10,20)
? test(30,40)
? test(10,20,20)
? test(30,40,70)
FUNCTION test
LPARAMETERS tnParam1, tnParam2, tnBribePercent
IF PCOUNT() < 3
? "Old version"
RETURN m.tnParam1+m.tnParam2
ELSE
? "New version"
RETURN (m.tnParam1+m.tnParam2)*(1+m.tnBribePercent/100)
ENDIF

Нихренанипанятно, зачем нужно таким странным способом объединять две разные функции в одну:
CLEAR
? test1(10,20)
? test1(30,40)
? test2(10,20,20)
? test2(30,40,70)
FUNCTION test1
LPARAMETERS tnParam1, tnParam2
? "Old version"
RETURN m.tnParam1+m.tnParam2
FUNCTION test2
LPARAMETERS tnParam1, tnParam2, tnBribePercent
? "New version"
RETURN (m.tnParam1+m.tnParam2)*(1+m.tnBribePercent/100)



Исправлено 1 раз(а). Последнее : lulgu, 27.04.18 22:18
Ratings: 3 negative/0 positive
Re: Функция проверки существования переменной
akvvohinc
Автор

Сообщений: 4212
Откуда: Москва
Дата регистрации: 11.11.2008
Igor Korolyov
Для чего такое может понадобиться? Может быть "в консерватории" надо кой чего поправить, а не лячкать г*нокод

Согласен, что это "нехороший" (но быстрый и не трудоемкий) способ решения проблемы.
Но на вопрос "Для чего это может понадобиться?" я ответил, когда и приводил тот единственной пример использования функции TYPE() не по прямому назначению, который мне встречался на практике:
akvvohinc
Готовое приложение и функция, вызывающаяся многократно из всех его подсистем.
Возникает необходимость, чтобы при вызовах из части подсистем функция отрабатывала иначе, а править все случаи (допустим, их 1000) лень.
Тогда вместо 1000 правок добавляется переменная лишь в головную программу подсистемы, требующей другого поведения функции.

На самом деле проблема даже не в том, чтобы поправить эту 1000 вызовов, а в том, что одна и та же программа должна вызывать эту функцию так или иначе в зависимости от того, каким путем мы добрались до этой программы (из какой подсистемы, как я условно обозвал это выше). Путь этот может быть как угодно длинен и запутан, а передавать некий параметр сверху вниз по всей цепочке нерационально.
Ratings: 0 negative/0 positive
Re: Функция проверки существования переменной
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
А потом одна "подсистема" (А) обращается к другой (Б), скажем за банальным "итого по ведомости за прошлый месяц", и замечательным образом получает ДРУГОЙ результат, нежели получит пользователь напрямую запустивший тот же отчёт из подсистемы Б.
Это и есть непредсказуемое (и практически не отлаживаемое) поведение. И именно по причине
akvvohinc
Путь этот может быть как угодно длинен и запутан
так делать никогда не надо.
Впрочем, зачастую вообще лучше не трогать существующие функции (тем более внося в них такого рода зависимости), а писать новые, если потребуется "такое же но с перламутровыми пуговицами".
А для сложных систем понятие явного "контекста" гораздо более управляемое и "прямое" решение, нежели private переменные невесть откуда попадающие или не попадающие в конкретный метод/функцию. По крайней мере число таких контекстов можно свети к минимуму (не превышающему то же число "подсистем"), да и любой доступ к контексту можно отследить без проблем, тогда как число private переменных и точек их использования (если уж позволить их использовать в этих целях) контролю и ограничению не поддаётся.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Функция проверки существования переменной
akvvohinc
Автор

Сообщений: 4212
Откуда: Москва
Дата регистрации: 11.11.2008
Igor Korolyov
А потом одна "подсистема" (А) обращается к другой (Б), скажем за банальным "итого по ведомости за прошлый месяц", и замечательным образом получает ДРУГОЙ результат, нежели получит пользователь напрямую запустивший тот же отчёт из подсистемы Б.

Конечно, можно придумать свое приложение, где "подсистемы" работают так, как описываешь ты. Но в том случае, о котором писал я, такого (подсистема А обращается к подсистеме Б) быть не могло.

Просто я назвал все это слишком красиво - подсистема.
На деле же все несколько проще - в процессе эксплуатации готового приложения "вдруг" появляется программа А (одна единственная), для которой та функция должна отрабатывать иначе ВСЕГДА (если это не так, то это не наш случай ), причем, неважно, каким путем мы приходим к ее вызову - важно лишь, что где-то выше в стеке есть эта программа А. Это единственное, но необходимое условие.
Ratings: 0 negative/0 positive


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

On-line: 28 NSF hvh2007  (Гостей: 26)

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