Passing an Object as an argument to an external script.

I have a script saved in the file Untitled.scrpt

on run (inputArg)
	tell application "Mail"
		return (name of inputArg) as text
	end tell
end run

I have another script, in a different file.

set myScript to "Macintosh HD:Users:merickson:Desktop:Untitled.scpt" as alias

tell application "Mail"
	set myBox to a reference to mailbox "INBOX" of account "Yahoo"
end tell

run script myScript with parameters {myBox}

Which throws an error:
Can’t make «class mbxp» “INBOX” of «class mact» “Yahoo” of application “Mail” into the expected type.

However, when I cast Untitled as a method (in the same script file), it accepts the argument just fine.
When I pass a string value as an argument to a similar script, that works.

I have a two-fold question:

  1. Is there a different technique to pass an object as an argument to an external script?

  2. Accounting for the possiblity of nested mailboxes, can one pass a Mail mailbox as a string?

I played with this for a while. Eventually I hit upon the idea of wrapping the value in a script object. Here is a demonstration that shows it needs to be done both ways if you plan on returning application objects:

script unwrapping_helper
	on run args
		unwrap(first item of args)
	end run
end script

script rewrapping_helper
	on run args
		unwrap(first item of args)
		wrap(result)
	end run
end script

tell application "Mail" to mailbox "INBOX" of account "GMail/GMail"
wrap(result)
set params to {result}

set directly to stuff of first item of params
set fromUnwrappingHelper to run script unwrapping_helper with parameters params
set fromRewrappingHelper to stuff of (run script rewrapping_helper with parameters params)
{directly, fromUnwrappingHelper, fromRewrappingHelper}
(*
{mailbox "INBOX" of account "Gmail/Gmail" of application "Mail",¬
 mailbox "INBOX" of account "Gmail/Gmail",¬
 mailbox "INBOX" of account "Gmail/Gmail" of application "Mail"}
-- The "of application "Mail"" is missing from the non-wrapping helper.
*)

to unwrap(w)
	stuff of w
end unwrap
to wrapWithScript(o)
	script
		property stuff : o
		on run
			return o
		end run
	end script
end wrapWithScript
to wrapWithRecord(o)
	{stuff:o}
end wrapWithRecord
property wrap : wrapWithScript -- Change to wrapWithRecord to test wrapping the value in a record

I can not explain why it “works” though.

It also works with the scripts in different files:

-- ~/Desktop/Untitled.scpt
on run args
	stuff of first item of args
	using terms from application "Mail"
		{name, unread count, it} of result
	end using terms from
	script
		property stuff : result
	end script
end run

set helper to alias ((path to desktop folder as Unicode text) & "Untitled.scpt")
tell application "Mail" to mailbox "INBOX" of account "GMail/GMail"
script
	property stuff : result
end script
set params to {result}
set helperResult to stuff of (run script helper with parameters params)
using terms from application "Mail"
	{name, unread count} of third item of helperResult
end using terms from
{helperResult, result}
(*
{{"INBOX", 0, ¬ -- Got name and unread count back from helper
  mailbox "INBOX" of account "Gmail/Gmail" of application "Mail"},¬ -- Got undamaged app object back from helper
 {"INBOX", 0}} -- Demonstrate that the returned app object is undamaged
*)

As for nested mailboxes, you could try this:

set mailboxes to {}
repeat with mbp in {{"Gmail/Gmail", "INBOX"}, {missing value, "Go Stuff", "Dragon Go Server"}}
	set mbp to contents of mbp
	set end of mailboxes to resolveMailbox(mbp)
end repeat

set unreadCounts to {}
repeat with mbox in mailboxes
	set mbox to contents of mbox
	using terms from application "Mail"
		set end of unreadCounts to unread count of mbox
	end using terms from
end repeat
unreadCounts

{mailboxes, unreadCounts} --> {{mailbox "INBOX" of account "Gmail/Gmail" of application "Mail", mailbox "Go Stuff/Dragon Go Server" of application "Mail"}, {0, 0}}

to resolveMailbox(mailboxPath) -- { accountName | missing value, mailboxName, .}
	if first item of mailboxPath is not missing value then
		tell application "Mail" to set m to mailbox (second item of mailboxPath) of account (first item of mailboxPath)
	else
		tell application "Mail" to ¬
			set m to mailbox (second item of mailboxPath)
	end if
	if length of mailboxPath is greater than 2 then ¬
		repeat with mailboxName in items 3 through end of mailboxPath
			set mailboxName to contents of mailboxName -- deref implicit ref of repeat with . in loop
			using terms from application "Mail"
				set m to mailbox mailboxName of m
			end using terms from
		end repeat
	m
end resolveMailbox

Although, it might not even be necessary. I am not sure if it applies to “account” mailboxes, but you can reference non-account nested mailboxes with a single slash-delimited name:

tell application "Mail"
	set a to mailbox "Go Stuff/Dragon Go Server"
	set b to mailbox "Dragon Go Server" of mailbox "Go Stuff"
	{a is b, a, b} --> {true, mailbox "Go Stuff/Dragon Go Server" of application "Mail", mailbox "Go Stuff/Dragon Go Server" of application "Mail"}
end tell

Model: iBook G4 933
AppleScript: 1.10.7
Browser: Safari 4.0.2 (4530.19)
Operating System: Mac OS X (10.4)

inputArg is a list, so you want to ‘return name of item 1 of inputArg’.

On the machine I’m using at the moment, the ‘run script’ line works if it too is addressed to Mail. Maybe the application calling ‘run script’ tries to resolve references before passing them outside the script?

set myScript to ((path to desktop as Unicode text) & "Untitled.scpt") as alias

tell application "Mail"
	set myBox to mailbox "INBOX" of account "Yahoo"
end tell
--
tell application "Mail"
	run script myScript with parameters {myBox}
end tell

chrys, scipting objects are more advanced than I am, but they look like a strong tool. I need to learn more.

Nigel, thanks! That worked fine. Passing it as the object rather than a reference worked for me too.

Thanks a bunch.

(How do I mark the thread as SOLVED?)

Thanks again.