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

Тема в разделе "Lotus - Программирование", создана пользователем leiba, 25 мар 2011.

  1. leiba

    leiba Lotus team
    Lotus team

    Регистрация:
    18 июн 2010
    Сообщения:
    47
    Симпатии:
    0
    Задался таким вопросом.
    Функция возвращает значение глобальной переменной. Имя переменной вычисляется во вне и передается в функцию как параметр.
    Как бы это сделать?
     
  2. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    Execute?

    Добавлено:
    Код (LotusScript):
    Execute "anotherGlobalVar = " & parameter
    resultofFunction = anotherGlobalVar
     
  3. leiba

    leiba Lotus team
    Lotus team

    Регистрация:
    18 июн 2010
    Сообщения:
    47
    Симпатии:
    0
    Точно! Спасибо, получилось.
     
  4. NickProstoNick

    NickProstoNick Статус как статус :)

    Регистрация:
    22 авг 2008
    Сообщения:
    1.766
    Симпатии:
    39
    Зачем так? Execute же работает только с публичными переменными и функциями.
    По идее anotherGlobalVar должна быть публичной
    Или я чего-то не понял?
     
  5. nvyush

    nvyush Lotus team
    Lotus team

    Регистрация:
    22 апр 2009
    Сообщения:
    2.317
    Симпатии:
    0
    Если речь о глобальных переменных, то вместо
    Код (LotusScript):
    someVarable = myFunctionGetGlobalVarByName("GlobalVarName")
    не проще ли написать:
    Код (LotusScript):
    someVarable = GlobalVarName
    ???
     
  6. hosm

    hosm * so what *

    Регистрация:
    18 май 2009
    Сообщения:
    2.450
    Симпатии:
    7
    правильно понял. Но я не помню, как иначе - не уверена, что правильно сработает присваивание результата обычной ф-ции напрямую без переменной в экзекьюте. насколько помню, юзала через глобальную переменную (public). Если работает - пожалуйста, расписываюсь в своем неведении =)
     
  7. leiba

    leiba Lotus team
    Lotus team

    Регистрация:
    18 июн 2010
    Сообщения:
    47
    Симпатии:
    0
    anotherGlobalVar - глобальная переменная в том же модуле и служит для передачи значения.
    Проблема в том, что имя переменной заранее неизвестно и передается как параметр
    то есть был такой код:
    Код (LotusScript):
        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
    теперь так
    Код (LotusScript):
    Property Get getConstant(xName As String) As String
    '! начало property
    Execute ({xRet = }+xName)
    getConstant = xRet     
    '! конец property
    End Property
     
  8. NickProstoNick

    NickProstoNick Статус как статус :)

    Регистрация:
    22 авг 2008
    Сообщения:
    1.766
    Симпатии:
    39
    т.е. фактически ты вызываешь например так
    Код (LotusScript):
    Execute ({xRet = getConstant( "CFGFIELD_NSI" ) })
    А чем это будет отличаться если Property Get getConstant будет публичным?

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

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.080
    Симпатии:
    300
    есть задачи где возможно использование Execute...
    например:
    - не хочется залезать в код, а поменять набор переменных в декларациях
    - отображение имен переменных и их значений (совместно с первым пунктом)
    - сделать что-то типа плагинов
    ....
    в основной массе задач - не вижу смысла заморачиваться
     
  10. NickProstoNick

    NickProstoNick Статус как статус :)

    Регистрация:
    22 авг 2008
    Сообщения:
    1.766
    Симпатии:
    39
    Ну чего, для общего развития интересно :)
     
  11. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    Глобальные переменные и 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">
    Код (Text):
    ' Абстрактный контекст выполнения
    ' Переопределяется в клиентах библиотеки
    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
     
  12. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.080
    Симпатии:
    300
    меня тоже мучает этот вопрос ;)
    я заметил тенденцию к изобретению головняка, у части мемберов форума...
    весна, видать, так действует :)
     
  13. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    пятничный OFF:
    желание изобретать велосипеды рано или поздно проходит.
    Я тут слазил в собственный проект семилетней давности и вздрогнул :) Самое смешное, этот ужос успешно работает и решает все поставленные задачи. А код такой, что хочется забиться в угол и зарыдать...
    Сделал вывод:наличие качественной архитектуры - не синоним успешного проекта. Приклад, слепленный из гамна, может работать годами и радовать пользователей. И, аналогично: гениально спроектированный проект может с треском провалиться, не оправдав ожиданий заказчика.

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

    leiba Lotus team
    Lotus team

    Регистрация:
    18 июн 2010
    Сообщения:
    47
    Симпатии:
    0
    Общую задачу излагал здесь
    В ходе её решения возникла задача - взять константу, определенную в динамически подгружаемой библиотеке. То есть хотелось функцию, которой передавал имя константы и получал её значение.

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

    Добавлено:
    За ссылку спасибо :)
     
  15. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.080
    Симпатии:
    300
    объедините конфигурации в базу и все либы будут черпать инфу оттудова
     
  16. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    Вам фактически нужен адаптер для конфигурационного документа. Для создания адаптера вы используете мапинг полей через глобальные переменные.
    Альтернативой глобальным переменным в данном случае могут быть:
    1. документ-адаптер: конфигурационный документ для конфигурационного документа. Там и прописывается мапинг.
      • Преимущества:
        - проста реализации, отсутствие проблем с инжектом в общую библиотеку.
        - для изменения мапинга не требуется прав дизайнера.
      • Недостатки:
        - нужно как-то создать эти документы, ибо просто накатить дизайном их не получится( можно, но сложно ).
    2. класс-адаптер, как описывал выше.
      • Преимущества:
        - стандартный профит при уходе от глобальных переменных;
        - инкапсуляция конфигурационного документа( общая библиотека вообще не знает о существовании документов, используя методы класса для получения данных. Впоследствии можно осуществить безболезненный редизайн конфигурационных документов или вообще отказаться от них - на общую библиотеку это никак не повлияет)
      • Недостатки:
        - как и глобальный переменные, экземпляр класса нужно как-то инжектить в общую библиотеку. Если библиотека процедурная, а не объектная - могут возникнуть сложности.
    Проблема перекомпиляции в данном случае специфична не задаче, а выбранному решению. Т.е. эту проблему вы придумали сами, изобретая решение основной задачи.
     
  17. leiba

    leiba Lotus team
    Lotus team

    Регистрация:
    18 июн 2010
    Сообщения:
    47
    Симпатии:
    0
    turumbay
    Спасибо. Очень убедительно и понятно.
     
  18. leiba

    leiba Lotus team
    Lotus team

    Регистрация:
    18 июн 2010
    Сообщения:
    47
    Симпатии:
    0
    turumbay
    А можешь написать недостатки решения, предложенного мной? :) Для статистики.
     
  19. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.080
    Симпатии:
    300
    у меня тоже есть порядочно позорного кода (делалось как временная затычка...)
    порой переписываю куски :)
     
  20. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    О недостатках глобальных переменных писать можно долго. Основная беда: никогда нельзя быть уверенным, что кто-то другой не изменил ее значение. Развернутый список проблем можно нагуглить.
    Execute лишает возможности воспользоваться компилятором для поиска ошибок, затрудняет отладку и поиск ошибок, открывает дыру в безопасности для врага или дурака.

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

Поделиться этой страницей