Overwriting methods gives property is read-only error? Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
iseahound
Posts: 1445
Joined: 13 Aug 2016, 21:04
Contact:

Overwriting methods gives property is read-only error?

Post by iseahound » 09 Jul 2021, 12:05

Why does overwriting methods like this not work:

Code: Select all

a := s()
a.say := (*) => MsgBox("spots off")
a.say()
class s {
   say => MsgBox("tikki spots on!")
}
but using DefineProp works fine?

Code: Select all

b := s()
b.DefineProp("say", {call: (*) => MsgBox("spots off")})
b.say()
class s {
   say => MsgBox("tikki spots on!")
}
I do not see how the property is read only, unless a.say in the first example is equivalent to a.prototype.say. In which case I am wondering why the individual descriptions get, set, call, and value are not used as references to the prototype, but rather the property itself.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Overwriting methods gives property is read-only error?

Post by swagfag » 09 Jul 2021, 12:51

its a feature.

By default, target.Method returns funcObj and attempting to assign to target.Method throws an error. These defaults can be overridden by defining a property or calling DefineProp.
https://lexikos.github.io/v2/docs/Objects.htm#Custom_Classes_method
a.say is equivalent to a.Base.say and s.Prototype.say

Code: Select all

class s {
   say => MsgBox("tikki spots on!")
}
this is a read-only property u have defined here. if u wanted to define a method, u should have written

Code: Select all

class s {
   say() => MsgBox("tikki spots on!")
}

I am wondering why the individual descriptions get, set, call, and value are not used as references to the prototype, but rather the property itself.
no idea what ure asking here.
get, set, call, and value are things relevant only to the Object that .DefineProp() requires and .GetOwnPropDesc() returns
iseahound
Posts: 1445
Joined: 13 Aug 2016, 21:04
Contact:

Re: Overwriting methods gives property is read-only error?

Post by iseahound » 09 Jul 2021, 23:13

So in other words, I am not assigning to the own property, but rather the base or prototype. Regarding methods and properties, I believe they were merged sometime back, but I could not find the exact details.
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: Overwriting methods gives property is read-only error?  Topic is solved

Post by swagfag » 10 Jul 2021, 16:34

in other words, when u do a.say :=
  • a is checked to see what kinds of properties of the same name it contains(if any at all)
  • a.Base is checked to see what kinds of properties of the same name it contains(if any at all)
  • a.Base.Base is then checked
  • a.Base.Base.Base next
  • and so on and so forth
then whichever case happens first:
  • if u found a read-only property(those are properties for which calling .GetOwnPropDesc() on would return an object containing no .Set or .Value properties), an exception is thrown saying u cant overwrite it
  • if u found a property with a setter, invoke the setter
  • if u found a value-property in a, overwrite it
  • if u ran out of bases to go through or u found a value-property in any of a's bases, create the value-property "say" in a, and assign to it whatever u wanted to assign to it

the "merging" was only relevant for the removal of .GetMethod(), .OwnMethods() and such like. properties are distinct from methods.
u can have this kind of object that defines a read-only property:

Code: Select all

class s {
   say => (this) => MsgBox("tikki spots on!")
}
or u can have this kind of object that defines a method:

Code: Select all

class s {
   say() => MsgBox("tikki spots on!")
}
or u can even have this kind of object that defines a value-property:

Code: Select all

class s {

}
s.Prototype.DefineProp('say', {value: (this) => MsgBox("tikki spots on!")})
and while to an observer it might seem like theyre all methods:

Code: Select all

a := s()
a.say()
u can clearly tell that theyre all different. and not only that, they can coexist:
While a property definition defines the get and set accessor functions for a property in the same way as DefineProp, a method definition defines the call accessor function. Any class may contain a property definition and a method definition with the same name. If a property without a call accessor function (a method) is called, get is invoked with no parameters and the result is then called as a method.
Post Reply

Return to “Ask for Help (v2)”