obj.HasKey() fails for all keys if a key called HasKey exists

Get help with using AutoHotkey and its commands and hotkeys
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

obj.HasKey() fails for all keys if a key called HasKey exists

12 May 2017, 06:16

[Moderator's note: Topic moved from Bug Reports.]

It seems that if a key called HasKey is added to an array, the HasKey method no longer works. Is this documented anywhere?

Of course I could create separate variables for handling situations where I would like a key with name HasKey, however, my main concern was whether there were any other unlikely key names that could cause issues with common object-related tasks. Thanks.

(It may seem an unlikely scenario, however, I have a spellchecker in AHK, that adds any words that have already been spellchecked, to an array, and it should be able to handle any word. Plus I do run spellchecks on AHK code, e.g. to retrieve variable names and non-words, or to spellcheck posts that contain AHK code.)

Code: Select all

q::
obj := {}
obj.a := "A"
MsgBox, % obj.HasKey("a") ;HasKey works
obj.HasKey := "HK"
MsgBox, % obj.HasKey("a") ;HasKey no longer works, always gives blanks
MsgBox, % obj.HasKey("HasKey")
MsgBox, % obj.a " " obj.HasKey ;it is still possible to retrieve values

;if the key 'HasKey' is deleted, then HasKey works again
obj.Delete("HasKey")
MsgBox, % obj.HasKey("a")
MsgBox, % obj.HasKey("HasKey")
obj := ""
return
==================================================

Btw for testing purposes what are the special AHK method names, have I missed any?

from https://autohotkey.com/docs/objects/Object.htm
_NewEnum,Clone,Delete,GetAddress,GetCapacity,HasKey,InsertAt,Length,MaxIndex,MinIndex,Pop,Push,RemoveAt,SetCapacity
also: __Call,__Delete,__Get,__New,__Set,base,Next
also+: __Class,__Init
deprecated: Insert,Remove

note: ObjXXX functions where XXX is not in list above: ObjAddRef,ObjBindMethod,Object,ObjNewEnum,ObjRawSet,ObjRelease
note: there is no standard 'Count' method

[EDIT:] A few items added to the list, thanks nnnik.
Last edited by jeeswg on 12 May 2017, 15:11, edited 9 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
nnnik
Posts: 4444
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: obj.HasKey() fails for all keys if a key called HasKey exists

12 May 2017, 07:53

You have missed __New and __Delete as well as base
Recommends AHK Studio
lexikos
Posts: 6731
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: obj.HasKey() fails for all keys if a key called HasKey exists

12 May 2017, 22:31

This is not a bug and is not specific to built-in methods in any way. An object cannot have both a key-value pair and a method with the same name/key, by nature of how members are inherited from a base object. JavaScript and Lua work a little differently, but have the same limitation.

It is also explicitly documented:
Although built-in method names such as "Length" can be used as keys, storing a value will prevent the corresponding method from being called (unless that value is a reference to the appropriate function, such as ObjLength).
Source: Objects
Is this documented anywhere?
If you have to ask, Bug Reports is the wrong forum to post in.
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: obj.HasKey() fails for all keys if a key called HasKey exists

13 May 2017, 03:16

[EDIT: For the record:
- I said 'Is this documented anywhere?', after spending some time trying to think up a way to suggest that the devs might not be at fault. I wasn't ecstatic to have those words used against me. C'est la vie.
- Only if you were already familiar with object classes, would you expect that keys/methods couldn't share a name. For example, in AHK it's OK to have variables/functions with the same name.
- Although I can use workarounds for myself, I would love such a class, if feasible, because I would find it pretty useful, and it would be very newbie-friendly, and wouldn't require long explanations or caveats. It would fit the AHK way.
- What belongs in Bug Reports isn't defined anywhere. Based on the posts I saw there, including 6 posts by me, my post was suitable. The post was moved. C'est la vie again.]

Thank you for your response. I really appreciate your detailed answers on my questions and questions by other people.

I think that the desire for a class that can handle any key is quite a reasonable one, perhaps a custom class can be made that can handle any key, and perhaps it would need '2 objects within 1 class'.

I did some tests on the Scripting.Dictionary object, if anyone can find any similar issues with this class I would be interested.

Code: Select all

;Dictionary Object
;https://msdn.microsoft.com/en-us/library/x4k5wbx4(v=vs.84).aspx

q::
oArray := ComObjCreate("Scripting.Dictionary")
oArray.item("MyKey") := "MK"
oArray.item("Exists") := "E"
oArray.item("item") := "i"
oArray.item("Item") := "I"
MsgBox, % oArray.Exists("MyKey") ;-1
MsgBox, % oArray.Exists("Exists") ;-1
MsgBox, % oArray.Exists("item") ;-1
MsgBox, % oArray.Exists("KeyThatDoesNotExist") ;0
MsgBox, % oArray.item("MyKey") ;MK
MsgBox, % oArray.item("Exists") ;E
MsgBox, % oArray.item("item") ;i
MsgBox, % oArray.item("Item") ;I
oArray := ""
return
Re. Bug Reports, is it not true that using your style of argumentation I could argue that something that behaves like a bug, or that departs from reasonable expectations or existing models (breaks the principle of least astonishment) can be considered a bug, and would be a bug even it were documented, and that something that can be considered a bug is eligible for Bug Reports?
Last edited by jeeswg on 21 Jan 2018, 11:50, edited 2 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
User avatar
jeeswg
Posts: 6904
Joined: 19 Dec 2016, 01:58
Location: UK

Re: obj.HasKey() fails for all keys if a key called HasKey exists

13 May 2017, 03:37

It appears that a workaround is to use ObjHasKey(obj, key) instead of obj.HasKey(key).
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
lexikos
Posts: 6731
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

Re: obj.HasKey() fails for all keys if a key called HasKey exists

13 May 2017, 17:29

perhaps a custom class can be made that can handle any key
I think I already have, but I haven't a clue how to find it. [Edit: BArray is probably the one I was thinking of. It's just a proof of concept, though. You would need to implement the other methods, the way I've implemented HasKey.]

It is not necessary to use a COM object; just don't store values directly in the object which you're calling methods on. Everything can be redirected through meta-methods (and normal methods for HasKey, etc.).
jeeswg wrote:is it not true that using your style of argumentation [...]
I'll rephrase. If there's uncertainty about whether something is a bug and not a documented feature, don't post in Bug Reports. Get confirmation first. If you have to ask whether it's documented, you're obviously uncertain. If it's definitely a documented feature and you want it changed, post in Wish List.

I'm not going to argue over the semantics of "bug" or "bug report". It's irrelevant and would be a waste of my time, which is what I'm trying to avoid by guiding users to post in Ask for Help before Bug Reports.

Return to “Ask For Help”

Who is online

Users browsing this forum: Bing [Bot], Escamillo, Google [Bot], Waldorine and 149 guests