A
Akupaka
Миша, люди, тебя не знающие, могут не понятьЭто не проще, а кривее!
Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе
Миша, люди, тебя не знающие, могут не понятьЭто не проще, а кривее!
Миша, люди, тебя не знающие, могут не понять
Private universe As TUniverse
Private Class TUniverse
Sub New()
Call BigBang()
End Sub
Private Function BigBang()
' Применяем(?) Большой Взрыв, для создания новой вселенной
End Function
End Class
Public Function getUniverse As Variant
If universe Is Nothing Then
Set universe = New TUniverse()
End If
Set getUniverse = universe
End Function
Private universe As TUniverse
Private Class TFakeClass
Sub New()
End Sub
End Class
Public Class TUniverse
Sub New( i_fake As TFakeClass)
Call BigBang()
End Sub
Private Function BigBang()
' Применяем Большой Взрыв, для создания новой вселенной
End Function
End Class
Public Function getUniverse As TUniverse
If universe Is Nothing Then
Set universe = New TUniverse( Nothing )
End If
Set getUniverse = universe
End Function
Sub New() , TUniverse( Nothing )
End Sub
голова не разваливается в себе держать? написал бы сам, что знаешь... а вдруг ты не такой и умный )))я еще не знаю
Зачем это здесь? Взрослый дятька пытаеца самоутверждаца в песочнице для малышей?ребята пишите, пишите, мне уже интересно что же топик сайдер имел ввиду и что же такое "редкое и экзотическое" я еще не знаю
глядишь сниму шляпу и переделаю что нибудь по новоузнанное :mellow:
+100открываем почтовый шаблон (если текущий знаком - берем новую версию ) и там редкие конструкции встречаются - почувствуй себя исследователем
дяько ужо давно утвердился, я подстегиваю, мну интересно шо будетВзрослый дятька пытаеца самоутверждаца
Весьма интересное решения, особенно для энумераций.Игры в singleton
Option Public
Option Declare
%REM
Class Test
Description: Comments for Class
%END REM
Private Class Test
End Class
Sub Initialize
End Sub
%REM
Function getTest
Description: Comments for Function
%END REM
Public Function getTest() As Variant
Dim test As New Test
Set getTest = test
End Function
Option Public
Option Declare
Use "Test"
Sub Initialize
Call getTest()
[u][b]Dim j As Test[/b][/u]
End Sub
Option Public
Option Declare
%REM
Type PrivateType
Description: Comments for Type
%END REM
Private Type PrivateType
foo As Boolean
End Type
%REM
Class Test
Description: Comments for Class
%END REM
Public Class Test
%REM
Sub New
Description: Comments for Sub
%END REM
Sub New()
Dim pt As PrivateType
Print pt.foo
End Sub
End Class
Sub Initialize
End Sub
%REM
Function getTest
Description: Comments for Function
%END REM
Public Function getTest() As Variant
Dim test As New Test
Set getTest = test
End Function
Option Public
Option Declare
Use "Test"
Sub Initialize
Call getTest()
[u][b]Dim pt As PrivateType[/b][/u]
End Sub
Столкнулся со следующей багофичей, связанной с областью видимости user-defined типов и классов:
1) Создаем библиотеку Test:
2) Создаем агент:Код:Option Public Option Declare %REM Class Test Description: Comments for Class %END REM Private Class Test End Class Sub Initialize End Sub %REM Function getTest Description: Comments for Function %END REM Public Function getTest() As Variant Dim test As New Test Set getTest = test End Function
Опа-на :blink: , приехали приватный класс, описанный в библиотеке теперь виден в агенте.Код:Option Public Option Declare Use "Test" Sub Initialize Call getTest() [u][b]Dim j As Test[/b][/u] End Sub
Идем дальше:
1) Модернизируем библиотеку2) и собственно агентКод:Option Public Option Declare %REM Type PrivateType Description: Comments for Type %END REM Private Type PrivateType foo As Boolean End Type %REM Class Test Description: Comments for Class %END REM Public Class Test %REM Sub New Description: Comments for Sub %END REM Sub New() Dim pt As PrivateType Print pt.foo End Sub End Class Sub Initialize End Sub %REM Function getTest Description: Comments for Function %END REM Public Function getTest() As Variant Dim test As New Test Set getTest = test End Function
Вообще сели в лужу :wacko:Код:Option Public Option Declare Use "Test" Sub Initialize Call getTest() [u][b]Dim pt As PrivateType[/b][/u] End Sub
Получается, вызывая публичный метод библиотеки, в котором фигурируется приватный user-defined ти или класс (в теле метода, либо конструктора/деструктора), имеем возможность использовать эти типы/классы
Сие открытие "накрывает медным тазом" идею1 и идею2 создания синглтона на лотусе B)
Option Public
Объявляет в модуле по умолчанию явное объявление ОВ Public.
Оператор используется в модуле только один раз. Он может предшествовать любым объявлениям в модуле. На уровне модуля оператор Option Public определяет ОВ для всех переменных, констант, процедур, типов и классов, определенные пользователем, а также для внешних процедур, и не определяет ОВ меток, переменных - ссылок или любых других неявно объявленных переменных.
Если переменная в типе, определенном пользователем или переменная - ссылка на объект имеют тип Public, то тип данных, на которые осуществляется ссылка, не могут быть типа Private. Ключевое слово Private отменяет действие Option Public.
А что с OnEvent не так? В хелпе всё подробно про него описано.Или то же On Event. Используете таймер? Напишите мне.
Наблюдение верное, вывод - нет. Компилятор действительно пропускает такую конструкцию, но воспользоваться этим не получится. Упадет в рантайме с соответвующим исключением. В исходном посте я указывал на возможность вызоваСтолкнулся со следующей багофичей, связанной с областью видимости user-defined типов и классов:
Получается, вызывая публичный метод библиотеки, в котором фигурируется приватный user-defined ти или класс (в теле метода, либо конструктора/деструктора), имеем возможность использовать эти типы/классы
Dim clientSideUniverse As New TUniverse( Nothing )
Option Public
Option Declare
Public Class Fake
End Class
Public Class Guard
Sub New(i_fake As Fake)
End Sub
End Class
Option Public
Option Declare
Use "Guard"
Public universe As TUniverse
Private Class Fake ' Приватная версия Fake, которая перекрывает публичную из Guard
End Class
Public Class TUniverse
' Порядок аргументов важен: Guard должен идти перед Fake.
' Guard идет первым аргументом и т.к. сам требует "публичной" версии Fake,
' то именно публичная версия будет видна компилятору в клиентском коде.
' Вторым аргументом конструктора ожидается приватная версия Fake, которая
' становится действительно приватной.
Sub New(i_guard As Guard, i_fake As Fake)
Call BigBang()
End Sub
Private Function BigBang()
' Применяем Большой Взрыв, для создания новой вселенной
End Function
End Class
Sub Initialize
Set universe = New TUniverse(Nothing, Nothing)
End Sub
Лотус заставляет нас извращаться из-за своей неполноценности :blink:Например, можно перекрыть приватный класс одноименным публичным (а-ля variable shadowing):
Действительно, слепо доверившись компилятору, я не удосужился проверить код при вызове B)Компилятор действительно пропускает такую конструкцию, но воспользоваться этим не получится. Упадет в рантайме с соответвующим исключением.
Игры в singleton.
Классический (GOF) синглтон на LS не реализуем во-первых, из-за невозможности создать приватный конструктор класса и, во-вторых, из-за "локального" контекста выполнения(отсутствия переменных, глобальных на уровне приложения). Проблемы глобальной видимость здесь трогать не буду, а вот за проблему приватного конструктора есть некоторые мысли...
В свое время было найден workaround:Ссылка скрыта от гостей.
Автор предлагает использовать в качестве синглтона приватный экземпляр приватного же класса, возвращая ссылку на него как на variant:
Идея, в общем, интересная, НО:Код:Private universe As TUniverse Private Class TUniverse Sub New() Call BigBang() End Sub Private Function BigBang() ' Применяем(?) Большой Взрыв, для создания новой вселенной End Function End Class Public Function getUniverse As Variant If universe Is Nothing Then Set universe = New TUniverse() End If Set getUniverse = universe End Function
Предложенная реализация паттерна отвратительна тем, что приходится обращаться с объектом как с variant-ом - т.е. все очепятки клиента вылезут только на этапе выполнения. Кроме того невозможно создать функцию, принимающую объект указанного типа как параметр. Данный минус решения (IMHO) перевешивают все возможные плюсы. Забиваем.
Предлагаю на суд общественности альтернативное решение.
Раз нельзя сделать закрытый конструктор, сделаем так, чтоб его невозможно было вызвать. Небольшая доработка напильником:И все прелести отлова ошибок на этапе компиляции снова доступны.Код:Private universe As TUniverse Private Class TFakeClass Sub New() End Sub End Class Public Class TUniverse Sub New( i_fake As TFakeClass) Call BigBang() End Sub Private Function BigBang() ' Применяем Большой Взрыв, для создания новой вселенной End Function End Class Public Function getUniverse As TUniverse If universe Is Nothing Then Set universe = New TUniverse( Nothing ) End If Set getUniverse = universe End Function
Т.к. конструктор требует параметром приватный класс - в клиентском коде создать новый экземпляр объекта не получится...
Единственная конструкция, которую пропустит компилятор - Dim clientSideUniverse As New TUniverse( Nothing ). Однако создать объект все равно не выйдет( ошибка времени выполнения ). При попытке унаследоваться от Вселенной с переопределением конструктора- также ляжет на этапе выполнения. Т.е. реально имеем паблик класс, экземпляр которого невозможно инстанцировать в клиентском коде. Эврика?Код:Sub New() , TUniverse( Nothing ) End Sub
З.Ы. Идея на самом деле родилась для совершенно другой задачи. Фактически требовалось передавать в функцию значение из фиксированного набора( enumeration ). Городить case и проверять входной параметр внутри функции - не выход, т.к. компилятор все равно позволяет ошибиться в клиентском коде.
При помощи данной техники мы можем объявить нужное количество экземпляров класса и пользоваться ими как элементами перечисления: INVOICE_STATUS_BLOCKED , INVOICE_STATUS_APPROVED и т.д.( будучи уверенным, что вызвать функцию с неверным параметром клиенту не удастся )
Обучение наступательной кибербезопасности в игровой форме. Начать игру!