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.

[format]Result:
error “Finder got an error: Can’t continue replace_chars.” number -1708[/format]

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

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:


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?):

[format]-1708 The script doesn’t understand the message. The event was not handled.[/format]

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

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.

My suggestion, which works on my computer:

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:

https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/conceptual/ASLR_about_handlers.html#//apple_ref/doc/uid/TP40000983-CH206-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.

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.

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.

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.

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.

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?


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

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:

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

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.

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.

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

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.

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.

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.

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.

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, b file[/b], folder or item which is a generic term for all previous specifiers for example


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

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

This can be coerced back to a reference

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

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

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

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.

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

[format]tell application “Finder”
get item 1
→ document file “Current.gpx” of desktop
(document file Current.gpx of desktop)
end tell[/format]

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.

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?

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

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

Good notes. Thank you.

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:

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

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:

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:

[format]
(alpha bravo charlie delta echo)
(alpha bravo charlie delta echo)
(alpha_bravo_charlie_delta_echo)
(alpha_bravo_charlie_delta_echo)[/format]

Here’s my test script for modifying new foldernames, replacing " " with “_”:

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}:

[format]error “Finder got an error: Can’t continue replace_chars.” number -1708[/format]

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