guest3456 wrote:if a byref key variable is passed, and the key was empty string "", then querying this var after the call would return an empty string, which might lead the user to think that it was never assigned a return value.
Who's going to write code like this?
Code: Select all
If a user writes that and gets confused, I know where I'd place the blame. The right way to write it is (in my opinion) also the most obvious way (and that's the point):
Code: Select all
if object.HasValue(value, key)
... use key ...
what about returning the key directly and having a note in the docs to be careful when using it as a boolean because obviously key 0 or "" would look like its false?
That would be more likely to confuse. To clarify the result, one would have to do something like
if (key != "" || object[key] = value)
, or to be more robust,
if (key != "" || object.HasKey(key) && object[key] = value)
, if the value could be "". It would be making both the user and the code do more work when the method could have just returned a clear result in the first place.
I had (re)considered adding an
value, but even with that, one has to remember to write
if object.HasValue(value) != undefined
rather than the more obvious and semantically correct (according to the meaning of the name, not the behaviour)
if object.FindValue(value) != undefined
might be less confusing, but since
would work most of the time, it's still a trap someone will fall into.)
does it make sense to disallow 0 or "" as obj keys?
No. Anyway, strings that convert to the number 0 are also considered false.
another question: if multiple keys have the same value, which key gets returned to the byref param?
The first one found, the same as if you used a for-loop. (In other words, the key lowest in the sort order, which is not guaranteed by the documentation.) One would not use the method when both 1) the object contains duplicate values and 2) it matters which key is returned; because there's no way to get the second
key with that value (unless there are additional parameters like I mentioned in my first post).
i guess the first in the enumeration order, but how does that go when the obj is an assoc array with mixed keys of both strings and ints?
You can run a for-loop and find out.
nnnik wrote:When you need to do ByRef ( unless it is for passing binaries ( which are also makeshift to me ) ) it actually means that you tried to get too much information out of 1 function/method.
I'm not sure whether to say "you're overgeneralising" or "that's just nonsense". Are functions only allowed to have a single scalar value as a result now? So we should have to query the mouse/control/window's position twice to get both coordinates, for instance?
There are many cases where the result(s) of some operation cannot be represented by a single value. Output parameters are used quite frequently in many common languages (generally those which lack multiple return values), obviously including AutoHotkey.
In this particular case (HasValue/Contains/KeyOf/FindValue, not "has this value" specifically), it is wasteful to search for a value within the object and then return incomplete information when it is found. With only a single return value, either we get a clear answer ("yes, the object has this value" or "no, it doesn't") and have to duplicate the work to get full information, or we get an ambiguous answer (such as "" which could be a key or mean "no value found") and we have to query the object again to clarify. If you want an inefficient
solution, you can stick with the existing user-defined functions.