I had a couple recent scripts where I wished I could use this. Would be a handy shortcut to have in AHK as well.
https://developer.mozilla.org/en-US/doc ... tructuring
Object destructuring
Re: Object destructuring
yep thats definitely a nice-to-have
Re: Object destructuring
Not sure how much work it'd take to have the parser recognize that. As I believe { and } are not allowed on the left side of an expression. But it certainly wouldn't be incorporated if no on brought it up!
Re: Object destructuring
Code: Select all
#Requires AutoHotkey v2.0-a138-7538f26f
Array.Prototype.DefineProp('Call', {Call: destruct})
destruct(thisArray, VarRefs*) {
itemCount := thisArray.Length
varCount := VarRefs.Length
Loop Min(itemCount, varCount)
{
i := A_Index
; only assign if...
if (VarRefs.Has(i) ; ...a variable was provided, and...
&& thisArray.Has(i)) ; ...a value exists(ie its not 'undefined')
%VarRefs[i]% := thisArray[i]
; this allows to omit variables for array elements u wish to ignore:
; eg ([10, 20, 30])(&a, , &c), ignore the '20' here
; also allows to provide defaults if the array element was undefined:
; eg ([10, , 30])(&a, &b := 'default', &c), b is assigned 'default'
}
Rest := []
; u asked for as much or more variables than there were array
; elements, so the is no Rest. return an empty array instead
if (varCount >= itemCount)
return Rest
restCount := itemCount - varCount
; setting the Length pre-fills the Rest array with undefineds, which
; is needed in case the Original array also contained undefineds
Rest.Length := restCount
Loop restCount
{
++i
; only assign if a value exists
if thisArray.Has(i)
Rest[A_Index] := thisArray[i]
; otherwise, it was undefined, so leave it undefined
}
return Rest
}
MyArray := [10, 20, , 40, 50]
Rest := MyArray(&a, &b := 'default', &c := 'default', , &e, &f := 'default')
; &d, ignored '40'
MsgBox(
'a: ' a '`n'
'b: ' b '`n'
'c: ' c '`n'
'd: was ingored`n'
'e: ' e '`n'
'f: ' f '`n'
'Rest.Length: ' Rest.Length
)
; if the array is not already in a variable, then additional ( ) are needed
for i, RestElement in ([10, 20, , 40, 50])(&a, &b)
{
if IsSet(RestElement)
MsgBox RestElement
else
MsgBox 'RestElement at index ' i ' is undefined'
}
MsgBox(
'a: ' a '`n'
'b: ' b '`n'
)
Re: Object destructuring
Neat concept and along the lines of the "wish" I asked but not exactly how I'd prefer it. Way to think out of the box!
-
- Posts: 63
- Joined: 02 Jul 2020, 11:55
Re: Object destructuring
I've tried to implement destructuring assignment in v2 before. The way I did it was to create an Item property with variadic parameters that expected VarRefs so that arrays and objects could be directly assigned to it. It worked perfectly with array assignment, and in fact I even had it working perfectly with recursive array assignment by having some internal counter inside the destructuring function to keep track of the recursion depth across nested calls. It was pretty sweet, I'm sure I still have it somewhere.
objects, functionally speaking, I'm pretty sure they worked just fine too in that they could be made to perform the assignments just the same, but there were too many quirks about them for me to be happy with the outcome. The big one is that object members are enumerated alphabetically rather than by order of insertion, meaning there's no reasonable way to map enumerated members to a list of supplied out variables unless you supply additional metadata with the variables. There's also no way to expose the out variable names to the object without supplying metadata with the variables, so there's no way to manually match the member names to the variables supplied either, unless you go out of your way to tell the function exactly which member names you actually want. It was just super ugly in general and I ended up giving up on it.
pretty sure @swagfag that this was one of my main pain points those many months ago when I was lamenting the loss of dynamic variable creation. I really think we lost something awesome with that feature change. Would be nice to maybe see a dedicated keyword to signify a created variable or something, I know the justification for the current behavior is scoping issues that arise with normal use of the deref operator, but I wonder if dedicated syntax could solve them. Le sigh
objects, functionally speaking, I'm pretty sure they worked just fine too in that they could be made to perform the assignments just the same, but there were too many quirks about them for me to be happy with the outcome. The big one is that object members are enumerated alphabetically rather than by order of insertion, meaning there's no reasonable way to map enumerated members to a list of supplied out variables unless you supply additional metadata with the variables. There's also no way to expose the out variable names to the object without supplying metadata with the variables, so there's no way to manually match the member names to the variables supplied either, unless you go out of your way to tell the function exactly which member names you actually want. It was just super ugly in general and I ended up giving up on it.
pretty sure @swagfag that this was one of my main pain points those many months ago when I was lamenting the loss of dynamic variable creation. I really think we lost something awesome with that feature change. Would be nice to maybe see a dedicated keyword to signify a created variable or something, I know the justification for the current behavior is scoping issues that arise with normal use of the deref operator, but I wonder if dedicated syntax could solve them. Le sigh
Re: Object destructuring
good oneI was lamenting the loss of dynamic variable creation. I really think we lost something awesome with that feature change.
Re: Object destructuring
cool, post it. maybe we can learn something new
there is:unless you supply additional metadata with the variables. There's also no way to expose the out variable names to the object without supplying metadata with the variables, so there's no way to manually match the member names to the variables supplied either, unless you go out of your way to tell the function exactly which member names you actually want.
Code: Select all
#Requires AutoHotkey v2.0-a138-7538f26f
(Object.DefineProp)(VarRef.Prototype, 'Name', {Get: this => StrGet(NumGet(ObjPtr(this), (A_PtrSize = 4) ? 64 : 56, 'Ptr'))})
MyVarRef := &myVar
MsgBox MyVarRef.Name
nah. awesome? arguable. useful? no. did it have its uses? yes, primarily only for the script developer and no one else. potential for misuse? enormous(see v1 pseudoarrays)
getting rid of it also simplifies the implementation and maintenance burden
Last edited by swagfag on 20 Jul 2021, 19:02, edited 2 times in total.
-
- Posts: 63
- Joined: 02 Jul 2020, 11:55
Who is online
Users browsing this forum: No registered users and 28 guests