Получение значения переменной в функции по параметру

leiba

Well-Known Member
Lotus team
18.06.2010
47
0
46
Москва
#1
Задался таким вопросом.
Функция возвращает значение глобальной переменной. Имя переменной вычисляется во вне и передается в функцию как параметр.
Как бы это сделать?
 

NickProstoNick

Статус как статус :)
Lotus team
22.08.2008
1 785
42
35
Киев
#4
Код:
Execute "anotherGlobalVar = " & parameter
resultofFunction = anotherGlobalVar
Зачем так? Execute же работает только с публичными переменными и функциями.
По идее anotherGlobalVar должна быть публичной
Или я чего-то не понял?
 

nvyush

Well-Known Member
Lotus team
22.04.2009
2 317
0
48
Подмосковье
#5
Задался таким вопросом.
Функция возвращает значение глобальной переменной. Имя переменной вычисляется во вне и передается в функцию как параметр.
Как бы это сделать?
Если речь о глобальных переменных, то вместо
Код:
someVarable = myFunctionGetGlobalVarByName("GlobalVarName")
не проще ли написать:
Код:
someVarable = GlobalVarName
???
 

hosm

* so what *
18.05.2009
2 442
9
42
Kiev, Ukraine
#6
Зачем так? Execute же работает только с публичными переменными и функциями.
По идее anotherGlobalVar должна быть публичной
Или я чего-то не понял?
правильно понял. Но я не помню, как иначе - не уверена, что правильно сработает присваивание результата обычной ф-ции напрямую без переменной в экзекьюте. насколько помню, юзала через глобальную переменную (public). Если работает - пожалуйста, расписываюсь в своем неведении =)
 

leiba

Well-Known Member
Lotus team
18.06.2010
47
0
46
Москва
#7
Зачем так? Execute же работает только с публичными переменными и функциями.
По идее anotherGlobalVar должна быть публичной
Или я чего-то не понял?
anotherGlobalVar - глобальная переменная в том же модуле и служит для передачи значения.
Если речь о глобальных переменных, то вместо
someVarable = myFunctionGetGlobalVarByName("GlobalVarName")
не проще ли написать:
someVarable = GlobalVarName
???
Проблема в том, что имя переменной заранее неизвестно и передается как параметр
то есть был такой код:
Код:
	Property Get getConstant(xName As String) As String
'! переменные
Dim xRet As String

Select Case xName
Case "CFGFIELD_NSI": xRet = CFGFIELD_NSI
Case "CFGFIELD_LOG": xRet = CFGFIELD_LOG
Case "CFGFIELD_INVOICE": xRet = CFGFIELD_INVOICE
Case Else :	xRet = {}	
End Select
getConstant = xRet
'! конец property
End Property
теперь так
Код:
Property Get getConstant(xName As String) As String
'! начало property
Execute ({xRet = }+xName)
getConstant = xRet		
'! конец property
End Property
 

NickProstoNick

Статус как статус :)
Lotus team
22.08.2008
1 785
42
35
Киев
#8
т.е. фактически ты вызываешь например так
Код:
Execute ({xRet = getConstant( "CFGFIELD_NSI" ) })
А чем это будет отличаться если Property Get getConstant будет публичным?

Мне просто не понятно в чем прикол (без издевательств)
Все, вопросов нет. Я упустил момент что это две библиотеки.
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 435
351
homepage.mac.com
#9
есть задачи где возможно использование Execute...
например:
- не хочется залезать в код, а поменять набор переменных в декларациях
- отображение имен переменных и их значений (совместно с первым пунктом)
- сделать что-то типа плагинов
....
в основной массе задач - не вижу смысла заморачиваться
 

NickProstoNick

Статус как статус :)
Lotus team
22.08.2008
1 785
42
35
Киев
#10
есть задачи где возможно использование Execute...
например:
- не хочется залезать в код, а поменять набор переменных в декларациях
- отображение имен переменных и их значений (совместно с первым пунктом)
- сделать что-то типа плагинов
....
в основной массе задач - не вижу смысла заморачиваться
Ну чего, для общего развития интересно :)
 
#11
Задался таким вопросом.
Функция возвращает значение глобальной переменной. Имя переменной вычисляется во вне и передается в функцию как параметр.
Как бы это сделать?
Глобальные переменные и Execute, будучи использованы независимо, обеспечат незабываемый головняк на протяжении всего жизненного цикла приложения. А замешав их в одной флаконе, можно добиться вообще феерических результатов.

как писать нечитаемый код, или гарантированная работа на всю жизнь

Если не секрет, какую задачу пытатесь решить таким способом? Почему не использовать внешние настройки - конфигурационный документ, файл, notes.ini и т.п.? Почему не использовать dependency injection в конструкторе или методах библиотеки?<div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">пример</div></div><div class="sp-body"><div class="sp-content">
Код:
' Абстрактный контекст выполнения
' Переопределяется в клиентах библиотеки
Class TContext
Public Function getSomething As String ' 
Error 1001 , Typename(Me) & {.} & Getthreadinfo(1) & { is abstract }
End Function
End Class

' Класс, выполняющий основную логику модуля
Class TCommonLogic
Private context As TContext
' текущий контекст задается в конструкторе класса
Sub new(i_context As TContext)
Set context = i_context
End Sub

' Метод, зависящий от контекста
Function doDatabaseSpecificStuff()
Dim somethingSpecific As String
somethingSpecific = context.getSomething()
' мегакод, использующий somethingSpecific 
End Function
End Class


'' Usage Example: создать конкретную реализацию TContext, передать ее в конструктор TCommonLogic
Class TConcreteContext As TContext
Public Function getSomething As String ' 
getSomething = "Current DB specific value"
End Function
End Class
Sub initialize()
Dim context As New TConcreteContext
Dim logic As New TCommonLogic( context )
Call logic.doDatabaseSpecificStuff()
End Sub
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 435
351
homepage.mac.com
#12
Если не секрет, какую задачу пытатесь решить таким способом? Почему не использовать внешние настройки - конфигурационный документ, файл, notes.ini и т.п.? Почему не использовать dependency injection в конструкторе или методах библиотеки?
меня тоже мучает этот вопрос ;)
я заметил тенденцию к изобретению головняка, у части мемберов форума...
весна, видать, так действует :)
 
#13
меня тоже мучает этот вопрос ;)
я заметил тенденцию к изобретению головняка, у части мемберов форума...
весна, видать, так действует :)
пятничный OFF:
желание изобретать велосипеды рано или поздно проходит.
Я тут слазил в собственный проект семилетней давности и вздрогнул :) Самое смешное, этот ужос успешно работает и решает все поставленные задачи. А код такой, что хочется забиться в угол и зарыдать...
Сделал вывод:наличие качественной архитектуры - не синоним успешного проекта. Приклад, слепленный из гамна, может работать годами и радовать пользователей. И, аналогично: гениально спроектированный проект может с треском провалиться, не оправдав ожиданий заказчика.

Но, при прочих равных, проекты с продуманной архитектурой легче и приятнее сопровождать. Плюс моральное удовольствие от "чистого" решения - награда разработчику за потраченный труд.
 

leiba

Well-Known Member
Lotus team
18.06.2010
47
0
46
Москва
#14
Если не секрет, какую задачу пытатесь решить таким способом? Почему не использовать внешние настройки - конфигурационный документ, файл, notes.ini и т.п.?
меня тоже мучает этот вопрос
Общую задачу излагал здесь
В ходе её решения возникла задача - взять константу, определенную в динамически подгружаемой библиотеке. То есть хотелось функцию, которой передавал имя константы и получал её значение.

Если возвращаться к исходной задаче, то конфигурационные документы во всех базах есть (слава богу получаются одинаковым образом), но реализация... ужасная. Одни и те же сущности определены в разных полях. Переделать это нереально. Вот и подумал, что имена этих полей можно задать в специальной библиотеке константами. Понятно, что для каждой БД эта биб-ка уникальна, но будет отличаться только значениями констант.
Данная библиотека используется общей для всех баз библиотекой. И только ей. В этой библиотеке определены функции получения тех или иных баз партнеров, а в каком поле конфигурационного документа задана ссылка на базу партнер определено в константах вышеозначенной специальной персональной библиотеке. Для того, чтобы не перекомпилировать каждый раз общую библиотеку при изменениях, решил персональную библиотеку (с константами) подгружать динамически. Всё...

Добавлено:
как писать нечитаемый код, или гарантированная работа на всю жизнь
За ссылку спасибо :)
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 435
351
homepage.mac.com
#15
объедините конфигурации в базу и все либы будут черпать инфу оттудова
 
#16
Если возвращаться к исходной задаче, то конфигурационные документы во всех базах есть (слава богу получаются одинаковым образом), но реализация... ужасная. Одни и те же сущности определены в разных полях. Переделать это нереально. Вот и подумал, что имена этих полей можно задать в специальной библиотеке константами.
Вам фактически нужен адаптер для конфигурационного документа. Для создания адаптера вы используете мапинг полей через глобальные переменные.
Альтернативой глобальным переменным в данном случае могут быть:
  1. документ-адаптер: конфигурационный документ для конфигурационного документа. Там и прописывается мапинг.
    • Преимущества:
      - проста реализации, отсутствие проблем с инжектом в общую библиотеку.
      - для изменения мапинга не требуется прав дизайнера.
    • Недостатки:
      - нужно как-то создать эти документы, ибо просто накатить дизайном их не получится( можно, но сложно ).
  2. класс-адаптер, как описывал выше.
    • Преимущества:
      - стандартный профит при уходе от глобальных переменных;
      - инкапсуляция конфигурационного документа( общая библиотека вообще не знает о существовании документов, используя методы класса для получения данных. Впоследствии можно осуществить безболезненный редизайн конфигурационных документов или вообще отказаться от них - на общую библиотеку это никак не повлияет)
    • Недостатки:
      - как и глобальный переменные, экземпляр класса нужно как-то инжектить в общую библиотеку. Если библиотека процедурная, а не объектная - могут возникнуть сложности.
Для того, чтобы не перекомпилировать каждый раз общую библиотеку при изменениях, решил персональную библиотеку (с константами) подгружать динамически. Всё...
Проблема перекомпиляции в данном случае специфична не задаче, а выбранному решению. Т.е. эту проблему вы придумали сами, изобретая решение основной задачи.
 

leiba

Well-Known Member
Lotus team
18.06.2010
47
0
46
Москва
#18
turumbay
А можешь написать недостатки решения, предложенного мной? :) Для статистики.
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 435
351
homepage.mac.com
#19
Самое смешное, этот ужос успешно работает и решает все поставленные задачи. А код такой, что хочется забиться в угол и зарыдать...
у меня тоже есть порядочно позорного кода (делалось как временная затычка...)
порой переписываю куски :)
 
#20
turumbay
А можешь написать недостатки решения, предложенного мной? :) Для статистики.
О недостатках глобальных переменных писать можно долго. Основная беда: никогда нельзя быть уверенным, что кто-то другой не изменил ее значение. Развернутый список проблем можно нагуглить.
Меня мама в детстве учила двум вещам:
1. не входить в лифт с незнакомыми дядьками
2. глобальные переменные - плохо
Execute лишает возможности воспользоваться компилятором для поиска ошибок, затрудняет отладку и поиск ошибок, открывает дыру в безопасности для врага или дурака.

Спайка глобальных переменных и execute позволяет добиться эффектных результатов. Можно, например, вторым менять значение первой: помогает замести следы и сбить погоню со следа.
Глобальные переменные и execute - очень мощные средства. И разрушения, которые можно причинить при их использовании тоже недетские.