See v1.1.16 - Properties, bug fixes and optimizations or the documentation. If in doubt, assume the information in this thread is not applicable.
Properties
I've uploaded a new alpha build with a new feature for testing.
Working example:
Code: Select all
class MyClass {
MyProperty {
get {
MsgBox Getting MyProperty.
return this._myProperty ; Return the property's value.
}
set {
MsgBox Setting MyProperty to %value%.
this._myProperty := value ; Do something with the value being assigned.
return value ; Return the property's new value.
}
}
}
x := new MyClass
MsgBox % "x.MyProperty was set to " (x.MyProperty := 42)
MsgBox % "x.MyProperty returned " x.MyProperty
Code: Select all
class MyClass {
WithoutParams {
;...
}
With[Params] {
;...
}
}
For accessing properties, all of the following are valid, but x must be a derived object, not the class itself:
Code: Select all
value := x.MyProperty
value := x.MyProperty[params]
value := x.MyProperty(params) ; Method calls are treated the same as [].
value := x["MyProperty", params]
x.MyProperty := value
x.MyProperty[params] := value
x.MyProperty(params) := value ; () is translated to [] at load time, as in previous versions.
x["MyProperty", params] := value
Each class can override the properties of its base class. Omitting get or set allows the respective operation to be handled by the base class, which could use a meta-function, property or simple static class variable. A property definition can explicitly call on the base-class behaviour by using base.MyProperty, with the following caveats:
- As with methods, this never triggers a meta-function.
- The object's base can't be accessed this way. If you defined a property named base (with getter), the object's base would be inaccessible because this.base invokes the property.
When the property definition is encountered at load time, it is translated into a Property object and two methods. When the Property is inherited by a derived object, instead of returning the Property, the getter or setter is called. An important consequence is that if MyClass is the exact class in which MyProperty is defined, MyClass.Property does not call the property - it returns the Property object.
Property Objects
Property.Get and Property.Set each hold a reference to a function which implements the respective operation. These can be modified, but can only a hold function reference (not any other type of object) or nothing. They can also be called - the first example above could have been written like this:
Code: Select all
; ...
MsgBox % "x.MyProperty was set to " MyClass.MyProperty.set(x, 42)
MsgBox % "x.MyProperty returned " MyClass.MyProperty.get(x)
Reusing Properties
Properties can be reused by other classes, or by the default base object. For example:
Code: Select all
class Extensions {
Length {
; StrLen is assigned directly to .get, for performance.
}
static Length.get := Extensions._def("Length", Func("StrLen"))
_def(P, ret) {
"".base[P] := this[P]
return ret
}
}
MsgBox % "string".Length
Currently the rules for how meta-functions work are complicated and error-prone, in addition to being a little cumbersome. I have long been considering how best to improve on it for v2, but the only satisfactory answer I came up with was to reduce the need for meta-functions - by implementing Properties. Please keep discussion about v2 to the v2 forum, not this thread.
Other Changes
Fixed objects so that if __Call assigns a value to the appropriate key and does not explicitly return, the value is automatically called. This was the original intent, and is consistent with __Get and __Set. Previously, the value was ignored and a built-in method was potentially called (but the next invocation would see the new field and call it).
Download v1.1.16.00-a01-019fb99 - contains a (ANSI), w (Unicode 32-bit) and x64 (Unicode 64-bit) builds.
I don't intend to provide binaries for compiled scripts. I do intend to merge the new features into v2 soon.