I do not know what the nature of the eight(!) edits to your original post are, but you still seem to be under a misunderstanding.
Method will never overwrite value property/dynamic property.
...
But currently, value property will overwrite method with same name, unlike how dynamic property or method behave.
There are only
two kinds of properties and
one namespace:
There are value properties and dynamic properties. Value properties simply contain a value. Dynamic properties do not contain a value, but instead call an accessor function depending on how they are accessed (get, set or call).
Source: Object - Methods & Properties | AutoHotkey v2
What you are calling a "method" is a dynamic property with a
call accessor. This is quite obvious when you are using DefineProp {call} to define it.
When you define
f() => in a class and then define
f => on an
instance of the class, the properties are owned by two different objects.
A value property implies all three operations:
get the value,
set a new value, and
call the value. An object which inherits a value property inherits each of these operations independently. If the derived object defines
call, that may be combined with the operations inherited by the value property. If the derived object defines a
value property or
all three operations, it cannot inherit anything.
Changing this so that an inherited
call accessor function takes precedence over a
value property would break existing scripts. It would also reduce performance, since every time you look up a
value property to be called, the program needs to keep searching up the entire chain of base objects to ensure there is no
call accessor function.
When you define a method with
this.DefineProp(name, {call}), it
will overwrite any value property owned by
this. If there is a dynamic property, it will only overwrite an existing
call function, while retaining any
get or
set.
To
overwrite a property is to replace it with a new property or value. When a derived object loses access to a base object's property (no longer inherits it) due to a new property being defined in the derived object, this is called
shadowing or
overriding, not
overwriting. I am not sure that you are correctly making this distinction.
Adding the capacity for a dynamic property to also hold a value would be entirely redundant, and may increase overall memory usage or code complexity. It would also cost me time to develop and document. I don't see the benefit.
A trivial way to achieve the same effect is as follows:
Code: Select all
x := DefineValueMethod({}, 'f', 41, this => MsgBox(this.f))
x.f() ; 41
x.f++
x.f() ; 42
DefineValueMethod(obj, name, value, method) =>
obj.DefineProp(name, {
call: method,
get: (this) => value,
set: (this, nv) => value := nv
})
"Allowing a getter/value and a method with the same name to be defined in the same class is an extension of this."
Since you have made an extension, how matter to extend again.
By "is an extension of this" I mean "is due to this". A dynamic property has
get,
set and
call functions. A property definition sets
get and/or
set and a method definition sets
call, therefore they can all coexist. A value property is not a dynamic property; they cannot coexist.
Descolada wrote:
Since AHK allows executing functions without any parenthesis, what would be the expected result in this case:
The expected result would be nothing. A is constructed without side-effects, f is retrieved without side-effects, then the instance of A is deleted.
A().f is
not a method call statement. It is the same as
x := A().f, except that x is not defined.
Parentheses can also be omitted when calling a method in this same context, but only when the target object is either a variable or a directly named property, such as
myVar.myMethod or
myVar.myProp.myMethod.
Source: Scripting Language | AutoHotkey v2
If you instead used
the expected result would be that the method f is called.
If there was no method f but only a value f = 1, this would throw an error because 1 can't be called.
How you define the property has no impact whatsoever on whether this tries to
call f or
get it. That's solely dependent on the syntax.