How can I coerce the "city" etc. out of the address book?

Could someone patiently explain the difference between these two scripts regarding lists?
Why can the city property be referenced in Script 1 but not Script 2?
How can I coerce the “city” etc. out of the address book?


-- Script 1
set tmp to {a:1, b:56, city:"1966"}
get city in tmp
------------------------------------------------
-- Script 2

global alist, tmp
set alist to {}
set tmp to {}

tell application "Address Book"
	set mySelection to selection
	repeat with aPerson in mySelection
		set tmp to properties of addresses of aPerson
	end repeat
end tell

get item 1 of item 1 of tmp -- ok; assuming you have selected an entry in address book with an address...
get city in item 1 of tmp -- ERROR
----------------------------

the property city is a part of the dictionary of AddressBook, so keep it in the tell block

global alist, tmp
set alist to {}
set tmp to {}

tell application "Address Book"
	set mySelection to selection
	repeat with aPerson in mySelection
		set tmp to properties of addresses of aPerson
	end repeat
	
	-- get item 1 of tmp
	get city of item 1 of tmp 
end tell

I thought because I set the “tmp” global variable, that I was referencing “city” from tmp, NOT the address book.?!

What’s going on?

Thanks.

The global variable isn’t needed, because all is in the same scope.
Although you have the record in a tmp variable, the labels of the record are a part of AddressBook’s dictionary (4-digit RawCode for city: az27)
Outside the tell block AppleScript itself has no idea about the label city and takes it just as a variable

Then shouldn’t the

get tmp

outside the tell block also give me an error?


tell application "Address Book"
	set tmp to {}
	set mySelection to selection
	repeat with aPerson in mySelection
		set aPersonsAddresses to addresses of aPerson
		log aPersonsAddresses
		repeat with anAddress in aPersonsAddresses
			set tmp to tmp & {label:label of anAddress, street:street of anAddress, city:city of anAddress, state:state of anAddress, zip:zip of anAddress}
		end repeat
	end repeat
end tell

get tmp

BTW. I am only getting one address on a contact with two addresses; {label:“home”, street:“555 Any Street”, city:“Indianapolis”, state:“IN”, zip:“46204”}. The event log proves it’s reading the 2nd address. Am I doing the

set tmp to tmp & ...

right? Is there a better way?

No, you read just the record without any comparison

to get all addresses use this


. 
set end of tmp to {label:label of anAddress, street:street of anAddress, city:city of anAddress, state:state of anAddress, zip:zip of anAddress}
.

There might be a better way. What are you going to accomplish with the data?

I don’t know why, but I used a double set of curly quotes and got it the way I expected…
I think I’m on track now, though I still am unsure about when variable have dependencies inside/outside tell blocks. I think the “get tmp” should/could return garbage outside the tell block without a global definition.

Thanks for your help!

tell application "Address Book"
	set tmp to {}
	set mySelection to selection
	repeat with aPerson in mySelection
		set _addresses to addresses of aPerson
		log _addresses
		repeat with anAddress in _addresses
			set tmp to tmp & {{label:label of anAddress, street:street of anAddress, city:city of anAddress, state:state of anAddress, zip:zip of anAddress, country:country of anAddress, country code:country code of anAddress}}
		end repeat
	end repeat
end tell

get tmp

2 Notes:

¢ the form

set end of x to y

is much faster and better than

set x to x & {{y}}

¢ the global definition of a variable and resolving the terminoloy of a dictionary are two totally different things

Thanks for the form; “set end of x to y”. And, thanks for the interest.
I am updating an old script for formatting addresses for foreign countries. I have a rather global family/friends network (England,France,USA,Switzerland,Canada). AB has a global option for this, but doesn’t handle it very well if you address many countries.
ie. FRANCE prefers;

LASTNAME Firstname
Street
ZIP City
COUNTRY

I will use the country codes to process preferred formats when addressing envelopes (instead of Merge addressbook cards in “Pages”). I also still use delimeters in the AB:notes field for processing envelopes with difficult naming conventions such as “Dr. Dan Jones and Mrs. Wanda Smith”, or adding “and Family” at Xmas time etc.

Hope that helps in your understanding…

I got it :slight_smile:

To avoid terminology clashes I would prefer neutral variable names

tell application "Address Book"
	set tmp to {}
	set mySelection to selection
	repeat with aPerson in mySelection
		set _addresses to addresses of aPerson
		log _addresses
		repeat with anAddress in _addresses
			tell anAddress
				set end of tmp to {theLabel:label, theStreet:street, theCity:city, theState:state, theZip:zip, theCountry:country, countryCode:country code}
			end tell
		end repeat
	end repeat
end tell

get tmp

Good point. I agree, the variable names will be changed… _city, _state, etc.

Thanks StefanK.