Bug: GuiCtrl.Pos[xyhw]
Posted: 20 Oct 2018, 16:57
You can only access the values in GuiCtrl.Pos with a ., as in GuiCtrl.Pos.x. GuiCtrl.Pos['x'] gives an error.
Let's help each other out
https://www.autohotkey.com/boards/
https://www.autohotkey.com/boards/viewtopic.php?f=37&t=58098
Code: Select all
G := GuiCreate()
Ctrl := G.Add("Text")
G.Show("w100 h100")
MsgBox(Ctrl.Pos.x) ;works
try MsgBox(Ctrl.Pos['x']) ;throws, 'invalid usage'
finally
{
Arr := Ctrl.Pos
MsgBox(Arr['x']) ;works
ExitApp()
}
Code: Select all
gc := new guictrl
msgbox 'get attempt 1:`t' . (gc.pos.x)
msgbox 'get attempt 2:`t' . (gc['pos','x', 'y'])
msgbox 'get attempt 3:`t' . (gc.pos['x','y','z'].x)
class guictrl {
_pos := {x:100}
pos[p*] {
get {
static ctr := 1
local
; show which parameters were passed
for k, v in p
s.= v '`n'
msgbox 'parameters passed, ' . 'attempt ' . (ctr++) . '`n`n' . s
return this._pos
}
}
}
Code: Select all
pos[p*] {
get {
if p.length()
return this._pos[p.1]
return this._pos
}
}
No, you do (GuiCtrl.pos)[xywh], or as swagfag showed.
This clearly is not the case. I can only see this as a bug or bad language design.x.y[z] is the same as x[y,z]
Clearly it is not literaly the same, but it is treated as if it was.This clearly is not the case.
It is multidimensional, it may not be a multidimensional linear array, but if it's going to behave like an object, then it should be accessed like one.Helgef wrote: ↑21 Oct 2018, 02:55x.y[z] is the same as x[y,z], which is not the same as x.y.z which is the same as (x.y).z. Basically, it means that when you do GuiCtrl.Pos['x'] you are treating the GuiCtrl object as if it was multidimensional, which it isn't, so there is an error. Example for custom properties,
or x["y"]["z"] in place of x.y["z"] until this is changed, if ever. But x.y[z] typically works for regular objects "seamlessly" until you start messing with the meta functions and it goes to shit.nnnik wrote: ↑21 Oct 2018, 03:06Yeah but I would use x.y[z] when I want to avoid the behavior of x[y,z].
At least that's how I would intuitively use it.
But now you have to use (x.y)[z] in order to make the last parameter dynamic.
This feels like a sort of trap that people would fall in regularily.
Code: Select all
Msgbox(Ctrl["pos"]["x"]) ; also works
; and let the record know that
MsgBox(Ctrl['pos'].x) ; works
Msgbox(Ctrl.pos['x']) ; doesn't work.
Code: Select all
if (infix_count && infix[infix_count - 1].symbol == SYM_DOT // obj.x[ ...
&& *omit_leading_whitespace(cp + 1) != ']') // not obj.x[]
{
// L36: This is something like obj.x[y] or obj.x[y]:=z, which should be treated
// as a single operation such as ObjGet(obj,"x",y) or ObjSet(obj,"x",y,z).
--infix_count;
// Below will change the SYM_DOT token into SYM_OBRACKET, keeping the existing deref struct.
}
Multidimensional objects is more a way of thinking, which is helpful sometimes, i.e, when we do x[y, z] we think that we access the value at [y, z] in x. It should be clear the ctrlobj doesn't have a value at [y, z] so ctrlobj[y, z] doesn't work. Now, x.y[z] is the syntax for passing parameters to properties, but the pos property of ctrlobj doesn't accept parameters, which can be deduced by the absence of documentation stating it does. So this fails too, as it should. My example demonstrates this.It is multidimensional, it may not be a multidimensional linear array
Yes, resolution of subobjects is left associative. Makes sense since it is like browsing through a folder hierarchy.Helgef wrote: x.y.z is the same as (x.y).z
Could you give a motivating example of the usefulness of this weird right-associativity?Helgef wrote: x.y[z] is the same as x[y,z]
I believe I already did.Could you give a motivating example
So would you like gui.controls[name] to be interpreted as (gui.controls)[name]? It would mean that gui.controls would need to (create and) return an array of all controls. That is potentally a lot of unnecessary work. Shall we not have properties with parameters? That would work ofc, we just use methods instead.I thought about it and it is useless.