Newbies guide to debugging Applescript Studio using the Log command

Debugging
From Wikipedia, the free encyclopedia
http://en.wikipedia.org/wiki/Debugging

Responding to a plea for help from http://bbs.applescript.net/viewtopic.php?id=18585

When I first started using Applescript Studio (Mac OS X 10.4 version), I tried Xcode’s debugger with breakpoints, but I quickly found using the debugger to be quite tedious and my poor old G4 was being swiftly and mercilessly pummelled by its demands :o. So I found a much better solution for me, using the log command. Some of you are maybe wondering “How do I see the output of these log commands?”. The Run Log (Shift-Command-R) in Xcode.

Begin by adding log commands to the start and end of handlers (either all handlers or handlers you suspect as being troublesome).

Example:

on awake from nib theObject
	log "START awake from nib"

	if name of theObject is equal to "TableView" then
		set theDataSource to make new data source at end of data sources with properties {name:"data"}
		make new data column at end of data columns of theDataSource with properties {name:"ID", sort order:ascending, sort type:numerical, sort case sensitivity:case insensitive}
		set sorted of theDataSource to true
		set sort column of theDataSource to data column "ID" of theDataSource
		set data source of theObject to theDataSource
	end if

	log "END awake from nib"
end awake from nib

on clicked theObject
	log "START clicked"

	if name of theObject is equal to "ButtonAdd" then
		set theTableView to table view "TableView" of scroll view "Scroll View" of window of theObject
		set theDataSource to data source of theTableView
		set theContents to contents of every data cell of every data row of theDataSauce
	end if

	log "END clicked"
end clicked

When the Application is run you’ll get an error and the Run Log will output something like this:

There is something wrong because “END clicked” did not appear in the Run Log.
So you might try adding a log command for the variable theContents.

on clicked theObject
	log "START clicked"

	if name of theObject is equal to "ButtonAdd" then
		set theTableView to table view "TableView" of scroll view "Scroll View" of window of theObject
		set theDataSource to data source of theTableView
		set theContents to contents of every data cell of every data row of theDataSauce
		log "theContents"
		log theContents
	end if

	log "END clicked"
end clicked

When the Application is run you’ll get an error and the Run Log will output something like this:

Not very helpful. In order to identify the offending code in the “on clicked” event handler you might try adding log “one”,“two” etc:

on clicked theObject
	log "START clicked"

	if name of theObject is equal to "ButtonAdd" then
		set theTableView to table view "TableView" of scroll view "Scroll View" of window of theObject
		log "one"
		set theDataSource to data source of theTableView
		log "two"
		set theContents to contents of every data cell of every data row of theDataSauce
		log "three"
		log "theContents"
		log theContents
	end if

	log "END clicked"
end clicked

When the Application is run you’ll get an error and the Run Log will output something like this:

Aha! The offending line is “set theContents to contents of every data cell of every data row of theDataSauce”, changing theDataSauce to theDataSource should fix things.

Now when the Application is run the Run Log will output something like this:

Good job! The Run Log is complete.

Tip: Handlers which contain “return” need the log “End” to be inserted before the “return” as anything past it in the handler is not executed.

Example:

on returnVariable()
	log "START returnVariable"

	set theVariable to current date
	log "END returnVariable"
	return theVariable
	-- anything past this point is not executed
end returnVariable

Tip: What happens when you no longer want the log messages? Add a property (debug_me in this example) and the handler update_status. If debug_me is true then the log commands are carried out. When the program is ready for release set debug_me to false, much quicker than commenting out or deleting the log commands.
Thanks to Jonathan Nathan and his script TablePopupCells where I discovered this tip.

Example:

property debug_me : true

on awake from nib theObject
	set object_name to name of the_object as string
	my update_status("START awake from nib " & object_name)

	if name of theObject is equal to "TableView" then
		set theDataSource to make new data source at end of data sources with properties {name:"data"}
		make new data column at end of data columns of theDataSource with properties {name:"ID", sort order:ascending, sort type:numerical, sort case sensitivity:case insensitive}
		set sorted of theDataSource to true
		set sort column of theDataSource to data column "ID" of theDataSource
		set data source of theObject to theDataSource
	end if

	my update_status("END awake from nib " & object_name)
end awake from nib

on update_status(the_message)
	if debug_me = true then log the_message
end update_status

Well, that’s what I do, if you have any tips or suggestions on better debugging please let us all know about it.

Model: Mac Mini G4 Mac OS X 10.4.8
Browser: Safari 419.3
Operating System: Mac OS X (10.4)

Good job Pizzacake.

Your post surely helps the rest of us not too comfortable with Xcode’s debugger.

Thanks for the tip. I do hope that others who might have better alternatives would come forward with theirs.

archseed :o