Enumeration В Lotusscript

Darkhan

Lotus team
14.12.2012
98
2
#1
Доброе время суток!
Продолжаю скромные попытки расширить возможности разработки на LS. На сей представляю на суд общественности прототип реализации enumeration.
P.S. идея была взята отсюда
Код:
%REM
Library EnumerationLibrary
Created Apr 25, 2013 by Administrator Administrator
Description: Comments for Library
%END REM
Option Public
Option Declare

%REM
Type SafetyType
Description: Comments for Type
%END REM
Private Type SafetyType
foo As Boolean
End Type

Private safetyObject As SafetyType

%REM
Class EnumerationObject
Description: Comments for Class
%END REM
Public Class EnumerationObject
Private enumName As String

%REM
Sub New
Description: Comments for Sub
%END REM
Sub New(safetyType As SafetyType, enumName As String)
me.enumName = UCase(enumName)
End Sub

%REM
Function toString
Description: Comments for Function
%END REM
Public Function toString() As String
toString = me.enumName
End Function

End Class
%REM
Class Fruit
Description: Comments for Class
%END REM
Public Class Fruit
Private enumApple As EnumerationObject
Private enumPeach As EnumerationObject
Private enumOrange As EnumerationObject

%REM
Sub New
Description: Comments for Sub
%END REM
Sub New(safetyType As SafetyType)

End Sub

%REM
Property Get APPLE
Description: Comments for Property Get
%END REM
Property Get APPLE As EnumerationObject
If me.enumApple Is Nothing Then
Set me.enumApple = New EnumerationObject(safetyObject, "Apple")
End If
Set APPLE = me.enumApple
End Property

%REM
Property Get PEACH
Description: Comments for Property Get
%END REM
Property Get PEACH As EnumerationObject
If me.enumPeach Is Nothing Then
Set me.enumPeach = New EnumerationObject(safetyObject, "Peach")
End If
Set PEACH = me.enumPeach
End Property	

%REM
Property Get ORANGE
Description: Comments for Property Get
%END REM
Property Get ORANGE As EnumerationObject
If me.enumOrange Is Nothing Then
Set me.enumOrange = New EnumerationObject(safetyObject, "Orange")
End If
Set ORANGE = me.enumOrange
End Property

End Class
%REM
Class Fruit
Description: Comments for Class
%END REM
Public Function Fruit() As Fruit
Static sFruit as Fruit
If sFruit Is Nothing Then
Set sFruit = New Fruit(safetyObject)
End If
Set Fruit = sFruit
End Function
Пример использования:
Код:
%REM
Agent test
Created Apr 25, 2013 by Administrator Administrator
Description: Comments for Agent
%END REM
Option Public
Option Declare
Use "EnumerationLibrary"
Sub Initialize
Call translate(Fruit().ORANGE)
End Sub

Sub Terminate

End Sub

%REM
Sub translate
Description: Comments for Sub
%END REM
Private Sub translate(e As EnumerationObject)
If e Is Fruit().APPLE Then
MsgBox "Яблоко"
ElseIf e Is Fruit().PEACH Then
MsgBox "Персик"
ElseIf e Is Fruit().ORANGE Then
MsgBox "Апельсин"
End If
End Sub
Новая реализация enumeration, в которой следующие изменения:
1) Добавления абстрактных классов: "Контейнер элементов enum", "Элемент enum"
2) Элементы enum пересены в list
3) По замечанию Imike, инициализация всех элементов происходит в самом начале
4) Из предыдущего пункта следует, что теперь есть возможность итерировать по всем элементам enum
Код:
%REM
Library EnumLibrary
Created Jun 20, 2013 by AdminKz
Description: Comments for Library
%END REM
Option Declare
%REM
Type SafetyType
Description: Comments for Type
%END REM
Private Type SafetyType
foo As Boolean
End Type

Private safetyType As SafetyType
Private Const ERROR_CALLING_ABSTRACT_METHOD = "ERROR_CALLING_ABSTRACT_METHOD"
%REM
Class AbstractEnum
Description: Абстрактный класс, для получения доступа к элементам enum
%END REM
Public Class AbstractEnum
'Список элементов enum
Public entries List As AbstractEnumEntry

%REM
Sub New
Description: "Приватный" конструктор
%END REM
Sub New(safetyType As SafetyType)
End Sub

Sub Delete
Erase entries
End Sub

%REM
Function createEntry
Description: Абстрактный метод
%END REM
Private Function createEntry(enumName As String) As AbstractEnumEntry
Error 1, ERROR_CALLING_ABSTRACT_METHOD
End Function

%REM
Function getEntry
Description: Возвращает элемент enum по наименованию вызывающей функции
%END REM
Private Function getEntry() As AbstractEnumEntry
Dim enumName As String
enumName = LSI_Info(12)

If Not isElement(entries(enumName)) Then
Set entries(enumName) = createEntry(enumName)
End If

Set getEntry = entries(enumName)
End Function

End Class
%REM
Class AbstractEnumEntry
Description: Абстрактный класс элемента enum
%END REM
Public Class AbstractEnumEntry
Private enumName As String

%REM
Sub New
Description: "Приватный" конструктор
%END REM
Sub New(safetyType As SafetyType, enumName As String)
me.enumName = UCase(enumName)
End Sub 

%REM
Function toString
Description: Наименование элемента enum
%END REM
Public Function toString() As String
toString = me.enumName
End Function

End Class
%REM
Class ColumnTypeEntry
Description: Comments for Class
%END REM
Public Class ColumnTypeEntry As AbstractEnumEntry

%REM
Sub New
Description: "Приватный" конструктор
%END REM
Sub New(safetyType As SafetyType, enumName As String)
End Sub

End Class
%REM
Class ColumnType
Description: Comments for Class
%END REM
Public Class ColumnType As AbstractEnum

%REM
Sub New
Description: "Приватный" конструктор
Инициализация всех элементов enum
%END REM
Sub New(safetyType As SafetyType)
Call ICON()
Call CHECKBOX()
End Sub

%REM
Function createEntry
Description: Переопределенный метод, возвращающий конктретный тип элемента enum
%END REM
Private Function createEntry(enumName As String) As AbstractEnumEntry
Set createEntry = New ColumnTypeEntry(safetyType, enumName)
End Function

%REM
Function ICON
Description: Иконка
%END REM
Public Function ICON() As ColumnTypeEntry
Set ICON = getEntry()
End Function

%REM
Function CHECKBOX
Description: Чекбокс
%END REM
Public Function CHECKBOX() As ColumnTypeEntry
Set CHECKBOX = getEntry()
End Function	

End Class
%REM
Class RowTypeEntry
Description: Comments for Class
%END REM
Public Class RowTypeEntry As AbstractEnumEntry
Private color As String
Private height As String

%REM
Sub New
Description: "Приватный" конструктор
%END REM
Sub New(safetyType As SafetyType, enumName As String)
End Sub

%REM
Sub initialize
Description: Расширенная инициализация (вызов доступен в пределах библиотеки)
%END REM
Public Sub initialize(safetyType As SafetyType, color As String, height As String)
me.color = color
me.height = height
End Sub

%REM
Function getColor
Description: Цвет
%END REM
Public Function getColor() As String
getColor = color
End Function

%REM
Function getHeight
Description: Высота
%END REM
Public Function getHeight() As String
getHeight = height
End Function

End Class
%REM
Class RowType
Description: Comments for Class
%END REM
Public Class RowType As AbstractEnum

%REM
Sub New
Description: "Приватный" конструктор
Расширенная инициализация всех элементов enum
%END REM
Sub New(safetyType As SafetyType)
Call SIMPLE().initialize(safetyType, "#FFFFFF", "10px")
Call EXPIRED().initialize(safetyType, "#CACACA", "15px")
Call IMPORTANT().initialize(safetyType, "#DEDEDE", "20px")
End Sub

%REM
Function createEntry
Description: Переопределенный метод, возвращающий конктретный тип элемента enum
%END REM
Private Function createEntry(enumName As String) As AbstractEnumEntry
Set createEntry = New RowTypeEntry(safetyType, enumName)
End Function

%REM
Function SIMPLE
Description: Обычный
%END REM
Public Function SIMPLE() As RowTypeEntry
Set SIMPLE = getEntry()
End Function

%REM
Function EXPIRED
Description: Просроченный
%END REM
Public Function EXPIRED() As RowTypeEntry
Set EXPIRED = getEntry()
End Function

%REM
Function IMPORTANT
Description: Важный
%END REM
Public Function IMPORTANT() As RowTypeEntry
Set IMPORTANT = getEntry()
End Function

End Class
Sub Terminate

End Sub
Public Function ColumnType As ColumnType
Static mColumnType As ColumnType
If mColumnType Is Nothing Then
Set mColumnType = New ColumnType(safetyType)
End If
Set ColumnType = mColumnType
End Function
Public Function RowType As RowType
Static mRowType As RowType
If mRowType Is Nothing Then
Set mRowType = New RowType(safetyType)
End If
Set RowType = mRowType
End Function
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 568
263
#2
а что будет если я вызову у одного объекта sFruit.ORANGE и sFruit.PEACH ?

Добавлено: я о том, что технически не дестроятся:
Private enumApple As EnumerationObject
Private enumPeach As EnumerationObject
Private enumOrange As EnumerationObject
при новом значении
 

Darkhan

Lotus team
14.12.2012
98
2
#3
lmike , не совсем понял связь
- при новом значении чего?
- и зачем им дестроиться?
а объект sFruit сам по себе приватный
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 568
263
#4
я о томже - что вся "защита" сводится к приватной переменной
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 568
263
#6
др. словами, сравнивая с джава - отсутствует объект (переменная e), кот. не является глобальным
ведь я получаю все ссылки на объекты синглтона
 

Darkhan

Lotus team
14.12.2012
98
2
#9
Т.е., вы хотите сказать, что следующая конструкция обречена на провал?
Код:
	Dim e As EnumerationObject
Set e = Fruit().PEACH
MsgBox e.toString()
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 568
263
#10
нет - я хочу сказать, что ф-ция Fruit() выдает глобальный объект с нефинализированными переменными, кот. инициализируюся динамически
к томуже, ничто не помешает мен получить тотже глобальный объект просто вызвав Fruit
и смысл прятать глобальный sFruit становится сомнительным
если уж используется ф-цию - глобальная переменная не нужна (Satatic вполне подходит)
 

Darkhan

Lotus team
14.12.2012
98
2
#11
Как вы вызовете Fruit, не создав его? (а создать без вызова Fruit() не получится)
В любом случае: вызов Fruit или Fruit() повлечет за собой вызов функции Fruit(), попробуйте через дебаггер
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 568
263
#12
вот ее и вызову и выходом получу глобальный объект
Set myFruit=Fruit()
и формально - инициализация должна пройти в блоке либы и сразу создать все объекты енум, и запретить их менять
прям в конструкторе создать и пропертя их будут отдавать (никакой динамики)
с дестроем я погорячился :O_0:
 

Darkhan

Lotus team
14.12.2012
98
2
#13
1) зачем впустую создавать объекты, если они возможно не понадобятся
2) изменять объекты не получится, так как нет Property Set
3) в любом случае мы будем иметь один инстанс Fruit
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 568
263
#14
Код:
  Sub New(safetyType As SafetyType)
Set me.enumApple = New EnumerationObject(safetyObject, "apple")
Set me.enumPeach = New EnumerationObject(safetyObject, "peach")
Set me.enumPeach = New EnumerationObject(safetyObject, "orange")
End Sub
....
Property Get ORANGE As EnumerationObject
Set ORANGE = me.enumOrange
End Property
....
Добавлено:
1) зачем впустую создавать объекты, если они возможно не понадобятся
затемже же - зачем существую статики
чтобы не проверять всякие ифы
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 568
263
#16
3) в любом случае мы будем иметь один инстанс Fruit
глобальная переменная видна во всей либе, а смысла в ней нет

Добавлено:
Код:
	Dim e As EnumerationObject
Set e = Fruit.Orange
Delete e
что будем делать тогда?
а что бум делать с Dim v:Set v=Fruit():Delete v :O_0:
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 568
263
#18
ничего, функция нам новую создаст))
угу при том что ссылки по прежним объектам дестроятся :O_0:
Код:
Private Sub translate(e As EnumerationObject)
Dim v
Set v=Fruit()
Delete v
If e Is Fruit().APPLE Then Msgbox "Яблоко"
If e Is Fruit().ORANGE Then	Msgbox "Апельсин"
If e Is Fruit().PEACH Then Msgbox "Персик"
End Sub
 

lmike

нет, пердело совершенство
Lotus team
27.08.2008
6 568
263
#20
изначально было пожелание
представляю на суд общественности
вот он и происходил :)
все вышеизложенное - это желание хоть как-то приблизить к java реализации (понятно - что с ограничениями)