Saturday, January 16, 2021

#1 2020-11-29 08:15:19 pm

daBee
Member
From:: Toronto
Registered: 2010-02-09
Posts: 156

Using Methods

Oh the frustration of AppleScript.  It haunts me.

I'm trying to use a method to replace some elements in a string.  I have my handler at the bottom of the script, and I've read that the handler has full scope over the whole script.  Not sure what's happening. 

Result:
error "Finder got an error: Can’t continue replace_chars." number -1708

This handler works in small test scripts so I'm not sure what is going on:

Applescript:

on replace_chars(this_text, search_string, replacement_string)
   -- replace_chars(message_string, "string_to_be_replaced", "replacement_string")    
   set AppleScript's text item delimiters to the search_string
   set the item_list to every text item of this_text
   set AppleScript's text item delimiters to the replacement_string
   set this_text to the item_list as string
   set AppleScript's text item delimiters to ""
   return this_text
end replace_chars

I have the application of this handler parked inside two tells:

Applescript:


tell application "iTunes"
   --blah blah blah
   tell application "Finder"
       set myVar to replace_chars(myFolder, " ", "_") -- this is where it happens
   end tell

   on replace_chars(...see above for handler...)

   end replace_chars
end tell

myVar doesn't get set for some reason.  Events feedback states that a proper myFolder parameter is submitted.  So I'm not sure why it isn't modified.  The error, which I had to research (why is this even needed?):

-1708  The script doesn’t understand the  message. The event was not handled.

Any help appreciated.  I find AS truly difficult to get through.

Last edited by daBee (2020-11-29 09:55:09 pm)


Filed under: handler, Error, Scope, Strings

Offline

 

#2 2020-11-29 09:01:36 pm

Fredrik71
Member
Registered: 2019-10-23
Posts: 594

Re: Using Methods

If you think its your handler... make a test case like this.

The handler use 3 strings as input and return string

Applescript:

return replace_chars("some text..", "text", "new text")

on replace_chars(this_text, search_string, replacement_string)
   -- replace_chars(message_string, "string_to_be_replaced", "replacement_string")    
   set AppleScript's text item delimiters to the search_string
   set the item_list to every text item of this_text
   set AppleScript's text item delimiters to the replacement_string
   set this_text to the item_list as string
   set AppleScript's text item delimiters to ""
   return this_text as text
end replace_chars

Now you know how the handler work...

Do not use tell block of Finder inside tell block of itunes.

Last edited by Fredrik71 (2020-11-29 09:11:06 pm)


The purpose to study someone else art is not to add, its to make less more.

Offline

 

#3 2020-11-29 09:49:38 pm

daBee
Member
From:: Toronto
Registered: 2010-02-09
Posts: 156

Re: Using Methods

I posted that the handler works.  I've tested that. 

Why can't I embed tells?  I'm building arrays inside that main iteration in itunes.  The script works just fine without the handler.  According to Apple's docs, the handler should be available everywhere.

Offline

 

#4 2020-11-29 10:07:37 pm

Fredrik71
Member
Registered: 2019-10-23
Posts: 594

Re: Using Methods

Its a good practice to separate the tell blocks...

tell application "Finder"
set var1 to something
end tell

tell application "iTunes"
set newVar to var1 to do something with my handler
end tell

this is what I mean with separate tell blocks.

Your code you put everything inside the tell block of iTunes.
The reason that is bad is because when you have a big script its will be difficult to
know where to call functions and more likely return error.

If you need data before iTunes this block it will be on top in your script.
if you make handlers it doesn't matter. You could call your handler everywhere in your script.


The purpose to study someone else art is not to add, its to make less more.

Offline

 

#5 2020-11-29 10:22:39 pm

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 731

Re: Using Methods

My suggestion, which works on my computer:

Applescript:

tell application "Podcasts"
   --blah blah blah
   tell application "Finder"
       set myVar to replace_chars("xxx xxx", " ", "_") of me --> "xxx_xxx"
   end tell
end tell

on replace_chars(this_text, search_string, replacement_string)
   -- replace_chars(message_string, "string_to_be_replaced", "replacement_string")
   set AppleScript's text item delimiters to the search_string
   set the item_list to every text item of this_text
   set AppleScript's text item delimiters to the replacement_string
   set this_text to the item_list as string
   set AppleScript's text item delimiters to ""
   return this_text
end replace_chars

The need for "of me" is explained in the AppleScript Language Guide as:

To call a handler from within a tell statement, you must use the reserved words of me or my to indicate that the handler is part of the script and not a command that should be sent to the target of the tell statement.



https://developer.apple.com/library/arc … 6-CJBIDBJH

FWIW, it's generally accepted that you should not have one tell statement inside another--perhaps you have some particular reason for doing this. Also, Script Editor changes iTunes to Podcasts on Catalina.

Last edited by peavine (2020-11-29 10:32:57 pm)


2018 Mac mini - macOS Catalina

Offline

 

#6 2020-11-29 10:30:16 pm

daBee
Member
From:: Toronto
Registered: 2010-02-09
Posts: 156

Re: Using Methods

Fredrik71 wrote:


Your code you put everything inside the tell block of iTunes.
The reason that is bad is because when you have a big script its will be difficult to
know where to call functions and more likely return error.



Functions are available across anything.  There's no scope to a function.  Hard coding a script when the resources are variable means you need to rewrite the script every time you use it.  You can't hard code everything.  That's the point of automation. 

Fredrik71 wrote:


If you need data before iTunes this block it will be on top in your script.
if you make handlers it doesn't matter. You could call your handler everywhere in your script.



The necessity of bouncing the focus inside various applications without being able to embed inside iterations is a failure of the language.  This would be my workflow:

Finder
iTunes
Finder

That should not be a requirement.  I will rewrite it once again, to pacify AS.  Let's see how this goes.

Offline

 

#7 2020-11-29 10:38:18 pm

daBee
Member
From:: Toronto
Registered: 2010-02-09
Posts: 156

Re: Using Methods

peavine wrote:

<snip>

The need for "of me" is explained at:

https://developer.apple.com/library/arc … mentID_361

FWIW, it's generally accepted that you should not have one tell statement inside another. Perhaps you have some particular reason for doing this. Also, Script Editor changes iTunes to Podcasts on Catalina.



I tried "of me" and it threw the same error.  I'm in El Capitan.  The reason I embedded it is because other languages won't allow the definition of the local variable outside the method.  Hence my recognition that setting a variable inside an application "tell" would lose scope outside that tell. 

Just tried using this handler and it didn't work after splitting up my tells.  The handler works in a test script just fine.

Offline

 

#8 2020-11-29 10:47:51 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6549

Re: Using Methods

You're likely to keep hitting walls if you keep trying to write for another language.

* Put in tell blocks what's relevant to them, and don't nest app tell blocks.

* Put handlers at the top level, not inside app tell blocks.

* Call handlers from within tell blocks by using my or of me.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Online

 

#9 2020-11-29 11:12:20 pm

daBee
Member
From:: Toronto
Registered: 2010-02-09
Posts: 156

Re: Using Methods

Shane Stanley wrote:

You're likely to keep hitting walls if you keep trying to write for another language.

* Put in tell blocks what's relevant to them, and don't nest app tell blocks.

* Put handlers at the top level, not inside app tell blocks.

* Call handlers from within tell blocks by using my or of me.



I'm rewriting a lot of this as I need to spoonfeed AS.  Tell blocks need to handle variables set in other tell blocks.  That's how data works. 

Apple has documentation saying handlers can be anywhere.  I have even tried them at the top.  I will include them in the top if I need to repost. 

I have tried "of me" and it gave me the same error.  A bit into the new rewrite, the handler isn't working still, but I'm still pushing.

Offline

 

#10 2020-11-29 11:22:18 pm

daBee
Member
From:: Toronto
Registered: 2010-02-09
Posts: 156

Re: Using Methods

OK, this hasn't moved one bit.  Heh.  I'm trying to write a script that replicates this issue and I can't even get the Finder to behave properly.

Why won't the folder get deleted?  I've coerced target as a folder.  Now the Finder is being picky about the path and the folder? 

Applescript:


set desktoppath to path to desktop
set target to (desktoppath & "tfolder") as text
log target

tell application "Finder"
   try
       delete folder target -- It won't do this
   end try
   make new folder at desktoppath with properties {name:"tfolder"}    
   set dingbat to choose folder with prompt "Choose a folder"
   log dingbat
   tell application "Finder" to delete dingbat    
end tell

Offline

 

#11 2020-11-29 11:49:00 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6549

Re: Using Methods

daBee wrote:

Applescript:


set desktoppath to path to desktop
set target to (desktoppath & "tfolder") as text



This isn't a good idea, because you're concatenating and alias and text, and it will use whatever your text item delimiters are at this point. It's inherently fragile. Instead, use:

Applescript:

set desktoppath to path to desktop as text
set target to desktoppath & "tfolder"

daBee wrote:

Applescript:

tell application "Finder"
   try
       delete folder target -- It won't do this



That's because target is a term defined in Finder's dictionary. If you look at your script, you'll see it's formatted differently there.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Online

 

#12 2020-11-30 12:02:37 am

daBee
Member
From:: Toronto
Registered: 2010-02-09
Posts: 156

Re: Using Methods

But then you have an instruction to delete something which is text. 

I'm really confused.  Paths are not text.  Text is just a string.  You can coerce a string into a folder somehow.  Is this a path again?  What about POSIX?  Are those strings or paths or text or something new?

Is there a standard when working with finder paths and instructions like this? 

BTW the "target" variable name didn't display differently as a reserved word, as it would have told me something was up.

Offline

 

#13 2020-11-30 12:10:08 am

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6549

Re: Using Methods

your instruction was fine except for the terminology clash. Change the variable to something like theTarget and see.

BTW the "target" variable name didn't display differently as a reserved word, as it would have told me something was up.



Then either your AppleScript formatting is poorly set-up in that it's not showing the distinction, or there's something wrong on your Mac.


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Online

 

#14 2020-11-30 12:14:18 am

daBee
Member
From:: Toronto
Registered: 2010-02-09
Posts: 156

Re: Using Methods

LOL there's plenty wrong with my Mac.  Different discussion.

I changed the reserved word and it behaved.  But still confusion about types and typecasting in AS.

Offline

 

#15 2020-11-30 12:30:45 am

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 731

Re: Using Methods

daBee wrote:

BTW the "target" variable name didn't display differently as a reserved word, as it would have told me something was up.




Target is a property of a Finder window. On my computer with Script Editor, target color-formats as a variable outside the Finder tell statement and it color-formats as a property inside the Finder tell statement.

Last edited by peavine (2020-11-30 12:40:04 am)


2018 Mac mini - macOS Catalina

Offline

 

#16 2020-11-30 12:34:19 am

KniazidisR
Member
From:: Greece
Registered: 2019-03-03
Posts: 1537

Re: Using Methods

path to command of scripting additions can really be confusing (path to....)

You just need to remember that this command does not return a path (otherwise - text, otherwise - string), but a reference of the AppleScript alias type (this is a large integer, not text), a reference (address) to an element of your computer's file system. This large integer (it looks as this: #FFFFFF0) is visible only to system, and you see only alias presentation of this address (alias "Hard disk:Users:Me:MyImage.png")

But, Unlikely the Finder reference, or Posix file reference, the AppleScript alias is special case of reference: it is a reference to reference. The system looks at byte with address (first reference), reads the contents of this byte, and the contents of this byte is second reference, then the system looks at contents of this second reference and the contents of this byte is contents of first byte of original file. That is, alias is a reference to a reference to a original file (or folder)

The final chord: what we call a file or folder is a reference, and what we call a path to a file or folder is a path.

Last edited by KniazidisR (2020-11-30 01:20:23 am)


Model: MacBook Pro
OS X: Catalina 10.15.4
Web Browser: Safari 13.1
Ram: 4 GB

Offline

 

#17 2020-11-30 02:38:37 am

StefanK
Member
From:: St. Gallen, Switzerland
Registered: 2006-10-21
Posts: 11714
Website

Re: Using Methods

daBee wrote:

But still confusion about types and typecasting in AS.



Some notes:

• "Macintosh HD:Users:me:Desktop:" is a string/text, also called an HFS path
• "/Users/me/Desktop/" is a string/text, also called a POSIX path
Important: The Finder doesn't support POSIX paths (however System Events does).
• To work with file system objects in the Finder you have to add specifiers to get a reference, either alias, alias file, disk, (document) file, folder or item which is a generic term for all previous specifiers for example

Applescript:


tell application "Finder"
   folder "Macintosh HD:Users:me:Desktop:"
end tell"

alias is a global specifier, the others are only related to the Finder (and System Events)
• Only alias can be coerced to POSIX path (as POSIX path).
• All Finder specifiers can be coerced to HFS path (as text) to be able to concatenate path components for example

Applescript:

set theFile to (path to desktop as text) & "file.ext"

This can be coerced back to a reference

Applescript:

tell application "Finder" to delete file theFile

Special case: As the desktop folder of the current user is the root folder of the Finder you need only the file name

Applescript:

tell application "Finder" to delete file "file.ext"


regards

Stefan

Offline

 

#18 2020-11-30 07:57:37 am

daBee
Member
From:: Toronto
Registered: 2010-02-09
Posts: 156

Re: Using Methods

peavine wrote:


Target is a property of a Finder window. On my computer with Script Editor, target color-formats as a variable outside the Finder tell statement and it color-formats as a property inside the Finder tell statement.



Ya that's where it tripped me up as it was along other instantiations with the same colour, outside the Finder tell.

Offline

 

#19 2020-11-30 08:09:20 am

daBee
Member
From:: Toronto
Registered: 2010-02-09
Posts: 156

Re: Using Methods

KniazidisR wrote:

path to command of scripting additions can really be confusing (path to....)

You just need to remember that this command does not return a path (otherwise - text, otherwise - string), but a reference of the AppleScript alias type (this is a large integer, not text), a reference (address) to an element of your computer's file system. This large integer (it looks as this: #FFFFFF0) is visible only to system, and you see only alias presentation of this address (alias "Hard disk:Users:Me:MyImage.png")



So a filesystem object UUID?  Essentially an untouchable item that I need to coerce to text for proper use?  Ruby has the same type of object notation.

Applescript:

tell application "Finder" to set mything to the first item
log mything

tell application "Finder"
    get item 1
        --> document file "Current.gpx" of desktop
    (*document file Current.gpx of desktop*)
end tell

So it is the object, of which a single property is the path of that object.  Using as text is a method that calls for the path. 

KniazidisR wrote:

But, Unlikely the Finder reference, or Posix file reference, the AppleScript alias is special case of reference: it is a reference to reference. The system looks at byte with address (first reference), reads the contents of this byte, and the contents of this byte is second reference, then the system looks at contents of this second reference and the contents of this byte is contents of first byte of original file. That is, alias is a reference to a reference to a original file (or folder)

The final chord: what we call a file or folder is a reference, and what we call a path to a file or folder is a path.



OK, any comment on why there are the two types of path references (both being texts)?  POSIX and the normal colon notation...switching back and forth is confusing as to why it's even there to begin with. 

So file -> path (POSIX path text or colon path text) -> alias

Is the path considered just a string, or is it fully representing its file as an object?

Offline

 

#20 2020-11-30 08:59:03 am

daBee
Member
From:: Toronto
Registered: 2010-02-09
Posts: 156

Re: Using Methods

StefanK wrote:


• All Finder specifiers can be coerced to HFS path (as text) to be able to concatenate path components for example

Applescript:

set theFile to (path to desktop as text) & "file.ext"

This can be coerced back to a reference

Applescript:

tell application "Finder" to delete file theFile



OK that's much more clear.  I keep assuming the text reference gives the ultimate type and location/path.  Not so. 

StefanK wrote:

Special case: As the desktop folder of the current user is the root folder of the Finder you need only the file name

Applescript:

tell application "Finder" to delete file "file.ext"



Ya I found that interesting as the Desktop is a child of the user. 

Good notes.  Thank you.

Offline

 

#21 2020-11-30 09:42:57 am

peavine
Member
From:: Prescott, Arizona
Registered: 2018-09-04
Posts: 731

Re: Using Methods

daBee wrote:

OK, any comment on why there are the two types of path references (both being texts)?  POSIX and the normal colon notation...switching back and forth is confusing as to why it's even there to begin with.



Some apps require POSIX paths, an example being shell commands. I suspect that's the primary reason for their use. If desired for some reason, they can be used in other circumstances, such as:

Applescript:

tell application "TextEdit" to open POSIX file "/Users/Robert/Working/New Text File.txt"

Last edited by peavine (2020-11-30 10:45:16 am)


2018 Mac mini - macOS Catalina

Offline

 

#22 2020-11-30 09:48:31 am

Fredrik71
Member
Registered: 2019-10-23
Posts: 594

Re: Using Methods


The purpose to study someone else art is not to add, its to make less more.

Offline

 

#23 2020-11-30 05:57:31 pm

daBee
Member
From:: Toronto
Registered: 2010-02-09
Posts: 156

Re: Using Methods

OK, thanks for the post on AS.  Back to the issue.  I'm having the same issue with that handler.  So first, I've tested the handler that works:

Applescript:

on replace_chars(this_text, search_string, replacement_string)
   -- replace_chars(message_string, "string_to_be_replaced", "replacement_string")    
   set AppleScript's text item delimiters to the search_string
   set the item_list to every text item of this_text
   set AppleScript's text item delimiters to the replacement_string
   set this_text to the item_list as string
   set AppleScript's text item delimiters to ""
   return this_text
end replace_chars

set f to "alpha bravo charlie delta echo"
log f -- (*alpha bravo charlie delta echo*)
replace_chars(f, " ", "_") -- works, but no output
log f -- no change to f, output (*alpha bravo charlie delta echo*)
log replace_chars("alpha bravo charlie delta echo", " ", "_") -- (*alpha_bravo_charlie_delta_echo*)
log replace_chars(f, " ", "_") -- (*alpha_bravo_charlie_delta_echo*)

Full list of Events:

(*alpha bravo charlie delta echo*)
(*alpha bravo charlie delta echo*)
(*alpha_bravo_charlie_delta_echo*)
(*alpha_bravo_charlie_delta_echo*)

Here's my test script for modifying new foldernames, replacing " " with "_":

Applescript:

on replace_chars(this_text, search_string, replacement_string)
   -- replace_chars(message_string, "string_to_be_replaced", "replacement_string")    
   set AppleScript's text item delimiters to the search_string
   set the item_list to every text item of this_text
   set AppleScript's text item delimiters to the replacement_string
   set this_text to the item_list as string
   set AppleScript's text item delimiters to ""
   return this_text
end replace_chars

set mylists to {"test 1", "another test 2", "third test playlist"}
set desktoppath to path to desktop
set basepath to (desktoppath & "tfolder") as text
log basepath

tell application "Finder"
   try
       delete folder basepath
       -- delay 2
   end try
   make new folder at desktoppath with properties {name:"tfolder"} -- This works
   
   repeat with this_playlist in mylists
       set myCompliantFolder to replace_chars(this_playlist, " ", "_") -- This is the highlighted method upon error
       set tester to basepath & this_playlist
       log myCompliantFolder
       log tester
       make new folder at basepath with properties {name:replace_chars(this_playlist, " ", "_")}
-- I've also tried the method in the first parameter placement, also doesn't work.
   end repeat
end tell

error, same result in both set myCompliantFolder and the first parameter inside the new folder property {name}:

error "Finder got an error: Can’t continue replace_chars." number -1708

So after cleaning it up, the error remains.  Not sure how to implement it as the previous one works.

Offline

 

#24 2020-11-30 06:05:45 pm

Shane Stanley
Member
From:: Australia
Registered: 2002-12-07
Posts: 6549

Re: Using Methods

Go back and read the quote from the ASLG in message #5 of this thread.

Applescript:

   make new folder at desktop with properties {name:my replace_chars(this_playlist, " ", "_")}


Shane Stanley <sstanley@myriad-com.com.au>
www.macosxautomation.com/applescript/apps/
latenightsw.com

Online

 

#25 2020-11-30 06:11:36 pm

daBee
Member
From:: Toronto
Registered: 2010-02-09
Posts: 156

Re: Using Methods

OK, thank you.  My previous attempt at using that didn't work for some reason.

Works now.

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)