tags:

views:

27

answers:

1

In VBScript, some built in objects use an unnamed property. Some Examples:

Set Dict = Server.CreateObject("Scripting.Dictionary")
Set RS = GetEmloyeesRecordSet()

Dict("Beer") = "Tasty"  ' Same as Dict.Item("Beer") = "Tasty"
Dict("Crude Oil") = "Gross" ' Same as Dict.Item("Crude Oil") = "Gross"

Response.Write "The First Employee Is: " & RS("Name") ' Same as RS.Fields("Name")

How can I use this same syntax in my own classes?

UPDATE

Here is a working, stand-alone example of how to do this, a simple wrapper for Scripting.Dictionary. Note the use of "Let" to allow the d("key") = "value" syntax. Of course credit goes to Thom for providing the answer.

<%
Class DictWrapper
    Private Dict

    Private Sub Class_Initialize()
        Set Dict = Server.CreateObject("Scripting.Dictionary")
    End Sub 

    Private Sub Class_Terminate()
        Set Dict = Nothing
    End Sub 

    Public Property Get Count
        Count = Dict.Count
    End Property

    Public Default Property Get Item( Key )
        Item = Dict(Key)
    End Property

    Public Property Let Item( Key, Value )
        Dict(Key) = Value
    End Property

    Public Sub Add( Key, Value )
        Dict.Add Key, Value 
    End Sub 

End Class

Dim d : Set d = New DictWrapper
d.Add "Beer", "Good"
Response.Write d("Beer") & "<br>"
d("Beer") = "Bad"
Response.Write d("Beer")
%>
+1  A: 

You need to declare a property of the class as the default property. As an example, here's part of a String wrapper class I wrote:

class StringClass
    private finished_
    private data_
    private size_

    public function init (val)
        finished_ = cStr(val)
        set init = me
    end function

    public default property get value
        if (size_ > 0) then
            finished_ = finished_ & join(data_, vbNullString)
            data_ = empty
            size_ = 0
        end if
        value = finished_
    end property

    public property let value (val)
        data_ = empty
        size_ = empty
        init(val)
    end property

    public function add (s)
        size_ = size_ + 1
        if (isEmpty(data_)) then
            redim data_(MIN_ARRAY_SIZE)
        elseif (size_ > uBound(data_)) then
            redim preserve data_(Float(uBound(data_) * GRANTED_HEAD_ROOM).ceil)
        end if
        data_(size_ - 1) = cStr(s)
    end function
end class

Usage: dim s: set s = new StringClass s()= "Hello, world!" ' s.value() = "Hello, world!" Response.Write s ' Response.Write s.value()

You can also have a parametrized default property:

class ListClass
    private size_
    private data_

    private sub CLASS_INITIALIZE
        size_ = 0
        data_ = Array()
        resize_array MIN_ARRAY_SIZE
    end sub

    public default property get data (index)
        if isObject(data) then
            set data_(index) = data
        else
            data_(index) = data
        end if
    end property

    public property let data (index, value)
        data_(index) = value
    end property

    public property set data (index, value)
        set data_(index) = value
    end property

    public function add(datum)
        size_ = size_ + 1
        if (size_ > uBound(data_) + 1) then expand_array

        assign data_(size_ - 1), datum

        add = datum
    end function
end class

dim l: set l = new ListClass
l.add("Hello, world!")
l(0) = "Goodbye, world!"
Response.Write l(0)

This second example is probably what you were looking for, using default properties to implement collections, but it's worth checking out the first example, using default properties to implement auto-unboxing of wrapper classes.

Thom Smith