So I was trying to remake some Array.prototype
functions from Javascript in Applescript. While trying to do that I noticed, that many Javascript functions use something that I think is called an arrow function.
Here is a little recap from what I understand of it:
Arrow functions are built up like this (shown by the Array.prototype.filter()
-method):
words.filter(word => word.length > 6);
^^^ ^^^ ^^^ ^^ ^^^
1 2 3 4 5
Example taken from mozilla.org.
- This specifies the array/list targeted. Easy to implement in Applescript.
- This specifies the built-in function used. I have no idea how to get this to work because I do not know how to implement steps 3, 4 and 5.
- This assigns the value that is "assigned" to each item in the list. This could be done statically with something like
repeat with word in words ...
(except for the fact that those words are reserved.), but I do not know of a way to do this dynamically. - This is the sign that "points" the compiler to tell it what should happen. I do not think that this is necessary to implement.
- This is (in this case) a comparison, whether a given word has a higher character count of 6. This decides if the item should stay in or not. This could be recreated using
if count of characters of word > 6 then set end of someNewListWeCreatedOutsideThisLoop to word
.
These arrow functions can also, instead of comparisons, have functions instead like forEach()
:
array1.forEach(element => console.log(element));
Example taken from mozilla.org.
Here is what I've tried:
on myFunc(fn)
fn
end
myFunc(log "Hello World")
This logs "Hello World" and afterwards throws an error about how not enough parameters were passed.
Here is a bit of a hacky workaround using the command line:
set theWords to {"These", "are", "Words."}
forEach(theWords, "theWord => log theWord")
on forEach(theArray, arrowFunction)
set AppleScript's text item delimiters to " => "
set arrowFunction to text items of arrowFunction
set AppleScript's text item delimiters to " "
return (do shell script "osascript -e 'repeat with " & item 1 of arrowFunction & " in (every word of \"" & (theArray as string) & "\")' -e '" & item 2 of arrowFunction & "' -e 'end repeat'")
end forEach
This method is supposed to work, and even if it would, it would have a tiring syntax, performance speed would be slow and I am almost sure that I have overlooked some stylish Applescript method.
CodePudding user response:
Wrap a handler containing your custom behavior in a script object. You can then pass the script object as a parameter to another handler and call it there.
script Foo
to doStuff(a, b)
return a b
end doStuff
end script
to bar(obj)
obj’s doStuff(1, 2)
end bar
bar(Foo)
--> 3
CodePudding user response:
Calling function from function in the AppleScript is possible, so following is closer to prototype of JavaScript. Not that you can assign to first function some better name than "prototype". For example, "wordsFilteringFunctions" to indicate that this prototype is designed for word filtering tasks.
UPDATE: If I understand correctly at least now, you want to control the behaviour of your prototype function based on some parameter. For example, based on the applied comparison sign like here:
set aList to words of "So I was trying to remake some Array.prototype functions from Javascript in Applescript. While trying to do that I noticed, that many Javascript functions use something that I think is called an arrow function."
prototype(aList, "<", 6)
on prototype(aList, operation, N)
if operation is ">" then
filterWithGreaterThan(aList, N)
else
filterWithLessThan(aList, N)
end if
end prototype
on filterWithLessThan(aList, N)
set filteredList to {}
repeat with anItem in aList
if length of anItem < 6 then set end of filteredList to contents of anItem
end repeat
return filteredList
end filterWithLessThan
on filterWithGreaterThan(aList, N)
set filteredList to {}
repeat with anItem in aList
if length of anItem > 6 then set end of filteredList to contents of anItem
end repeat
return filteredList
end filterWithGreaterThan