Think of something that you wish Authorware could do but it doesn't?  Let the our good friends at Macromedia know via the wishlist.

Please let us know if you find any of the materials on this site inappropriate or offensive. Please include the url and why the material should be reviewed.

Comments and questions about the site are also welcome. Please no Authorware questions, use the AWARE list.

Back

B7009 - What is the purpose of property lists? [Part 2]

by - Joseph Ganci


Many thanks for your swift response, you've probably no idea how useful it is for us to be able to tap into your knowledge. Have I got this right? You can mix linear list and property lists. For instance, you can have a list of property lists:

persons[id number][#name]
persons[id number][#street]
etc.

If I want to create a number of records in a normal database, I might do something like this:

ID      Names   Age
0001    Fred    18
0002    Bill    19
0003    Sue     18      etc...

In Authorware, I could use three linear lists called Id, Names, Age and refer to all the details about any one of these people.  Or a muti-dimensional list like this:

Id:=Array(0,3)
Names:=Array("",3)
Age:=Array(0,3)

Details:=[Id,Names,Age]

Id[1]:=001
Names[1]:="Fred"
Age[1]:=18

Id[2]:=002
Names[2]:="Bill"
Age[3]:=19
etc...

Is the intention that using property lists I would have one list with named fields,
Person[#id:0001,#Names:Fred, #Age:18]
which would record the details of the first person.

How then do I record the details of the second, third etc person?

I think that the idea is to let us get back the age of the 23rd person say, just by putting something like ValueAtIndex(Person,#age,23), although I realise that this wouldn't work as it is. I can see how AddProperty would create a new property, but what I would want is to have the same property but with many values, or am I completely missing the point?

Hello again. I was tracking down what I thought might have been a bug in Authorware, but as it turns out, it's not. It's just not as intuitive as I would have thought. So now I have your answer, and also a warning to those who may have thought as I did.

Originally, I was going to suggest that you could set up a linear list of property lists by using the following code:

people := Array( [#name:""] , 10)
people[1][#name] := "Joe"

However, the result of this is that all 10 property lists in the people array would have the value "Joe" as the value of the name property. So what gives?

Well, a little background is needed here. Remember that lists can contain gobs of data. I mean, GOBS of data. Normally, in Authorware, if you want to copy the value of a NON-LIST variable into another variable, you would use the approach:

>newvar := oldvar

If oldvar originally contained the value "Joe", then the value of newvar will also become "Joe". Take a look at the following:

oldvar := "Joe"
newvar := oldvar
oldvar := "Ivana"

After the above three lines are done, newvar will contain "Joe" and oldvar will contain "Ivana". Note that you can make any changes you wish to oldvar after you've set newvar to it, and the value of newvar doesn't change. That's because the value of oldvar is COPIED into newvar.

However, let's say you have created two lists, called mylist and yourlist. Take a look at the following:

mylist := ["Joe", "Ivana", "Frank", "Letha"]
yourlist := mylist
mylist := ["Bill"]

The result of the above is that yourlist and mylist will both contain ["Bill"]. The original value of mylist is destroyed. Why?

It's because when you set yourlist := mylist you are not making a copy of the contents of mylist into yourlist, but instead you are setting up yourlist as a reference to mylist. Any changes to one will happen to another.

When I teach Advanced Authorware classes, I use the following example (feel free to borrow it if you like it). Let's say you're married and your spouse and you just had your firstborn child, a girl. Now let's say you're partial to naming the child  "Melissa" and your spouse insists it must be "Susan." You both are very hardheaded and the little girl grows up being called Melissa by you and Susan by your spouse. She has two different names, but she is the same person in either case. So, here's the analogy now: if Melissa falls and scrapes her knee, is Susan's knee also scraped? Yes, of course, since she's the same little girl. When Susan goes to school, so does Melissa. When Melissa goes on her first date, so does Susan.

Since lists can potentially contain so much data, it makes sense that yourlist := mylist just create a reference, not a copy of the list. This makes sense more often than you may think. If, for instance, you set up a subroutine that manipulates a list in several ways, sorting it in a strange way that the SortList function can't handle, for instance, then you can set up the subroutine to use a list variable simply called "list". Whenever you have a list that needs to run through the subroutine, you then just have to set "list" to the list you want manipulated. So, if you have 20 lists in your file, and you want them all to be able to run through the subroutine, you don't have to COPY the contents of the list you want to run through the sub into the variable "list" and then have to copy the contents back into your list after the subroutine is finished. You need only set the variable list to the name of the variable you wish run through the subroutine. No need for massive copies at the beginning and end of the subroutine.

So, how does one copy a list into another list? One uses the CopyList function.

yourlist := CopyList(mylist)

makes a copy of mylist's values and places them into yourlist. This means you can make changes to either one and it doesn't affect the other.

So, getting back to the original question. Using the approach:

people := Array( [#name:""], 10)
people[1][#name] := "Joe"

is actually making 10 links to the same internal list. That's why making a change to the name property in the first location in the list makes the same change to all the locations in the list. Instead, you need to make copies in each location of the list, like this:

people := Array( [], 10)
repeat with i := 1 to ListCount(people)
  people[i] := CopyList([#name:""])
end repeat
people[1][#name] := "Joe"
people[8][#name] := "Ivana"

If you use the above approach, you'll see that "Joe" gets placed in the first location and "Ivana" in the eighth location, and the other locations behave, staying empty.

Long-winded, but I hope it helps explain further the intricacies of linear lists and property lists.

I followed your logic until here.  But what four indices are you referring to?

I mean that the Rect function returns a list variable that contains four locations.

If you set up a Rect function call as

myrect := Rect(20, 100, 60, 300)

then myrect[1] = 20 and myrect[2] = 100 and myrect[3] = 60 and myrect[4] = 300.

Those are the four indices, or locations, in the list.

There are 0 reviews
Add your review
Back