Re: lists and items and position of items
Re: lists and items and position of items
- Subject: Re: lists and items and position of items
- From: kai <email@hidden>
- Date: Sun, 13 Mar 2005 01:43:53 +0000
On Sat, 12 Mar 2005 17:08:01 +0100, Axel Luttgens wrote:
kai wrote:
[...]
For the benefit of those not familiar with this issue, Christian's
script was comparing strings like "Sal" with references like: item 1
of {"Sal", "Sue", "Bob", "Carl"}. While we might recognise these as
having essentially similar meanings, they differ nevertheless -
unless and until the reference is evaluated to an exact match, such
as (in this case): "Sal". Christian's 'list-position' handler
therefore found zero matches in every comparison.
[...]
Unless I'm wrong, one very precise point hasn't been made explicit
throughout the thread.
So, if you allow, I'll bring my 2 cents too...
As a general rule, AppleScript tends to automatically dereference and
coerce as needed. [1]
But the operator "is" in fact is very special in the language
specification: it first compares the classes of its operands, without
derefencing or coercing them.
So, in the following loop, x is always a reference and "Sal" is always
a string, hence the four consecutive falses:
set this_list to {"Sal", "Sue", "Bob", "Carl"}
repeat with x in this_list
log x is "Sal"
end repeat
--> (*false*)
--> (*false*)
--> (*false*)
--> (*false*)
By contrast, this is an illustration of AppleScript's usual behavior:
set this_list to {"Sal", "Sue", "Bob", "Carl"}
repeat with x in this_list
log x & "Sal"
end repeat
--> (*SalSal*)
--> (*SueSal*)
--> (*BobSal*)
--> (*CarlSal*)
In the above, on each pass, operator "&" dereferences x and gets a
string to which "Sal" may just be concatenated.
That's an interesting point, Axel - and easily worth more than 2
cents... :-)
Yes, it does seem to exemplify AppleScript's normal behavior -
particularly in terms of concatenation. Since the event log window
presents the referenced strings as commented text, AS evidently
attempts a coercion to string of any non-string values to the right of
the logged items. From that, I'd assume the dereferencing is driven (at
least in part) by concatenation.
Another example involving automatic dereferencing AND coercion:
set this_list to {1, 2, 3, 4}
repeat with x in this_list
log "Sal" & x
end repeat
--> (*Sal1*)
--> (*Sal2*)
--> (*Sal3*)
--> (*Sal4*)
So, yes, the "repeat with ... in ..." indeed is special in that the
looping variable is set to consecutive references.
But this mainly leads to surprises when used in conjubction with those
very special operators "is" and "is not".
Again, it looks as if concatenation is an influencing factor. To
explore the possibility a little further, I tried this:
--------------
set l to {"text", 2, false, path to "desk"}
repeat with i in l
log i & 1
end repeat
--> (*text1*)
--> (*2, 1*)
--> (*false, 1*)
--> (*alias Macintosh HD:Users:kai:Desktop:, 1*)
--------------
In the first iteration, where i is a reference to a string, it appears
to be evaluated as the original string - to which the integer (1) -
coerced to a string in the process - is then concatenated. In all other
cases, where the right-hand value can't be coerced to the same class as
the left-hand operand, a list results.
This behaviour is echoed by both of the following snippets, in which
the first item of each resulting list confirms 'raw' variable values,
while the second shows the effect of concatenation:
--------------
set t to "text"
set x to a reference to t
set y to 1
{{x, y}, x & y}
--> {{t of «script», 1}, "text1"}
--------------
set n to 2
set x to a reference to n
set y to 1
{{x, y}, x & y}
--> {{n of «script», 1}, {2, 1}}
--------------
It's also interesting to note what happens in the absence of any
logging or concatenation. A simple reference is normally evaluated and
displayed in Script Editor's Result window/pane in this way:
--------------
set l to {"one", "two", "three"}
set n to 1
set r to item n of l
r
--> "one"
--------------
In terms of repeat loops, this might be considered equivalent to the
'repeat with n from x to y' form:
--------------
set l to {"one", "two", "three"}
set r to {}
repeat with n from 1 to count l
set r's end to item n of l
end repeat
r
--> {"one", "two", "three"}
--------------
However, by using the operator 'a reference to', the value of the
variable 'r' is expressed as a reference:
--------------
set l to {"one", "two", "three"}
set n to 1
set r to a reference to item n of l
r
--> item 1 of {"one", "two", "three"}
--------------
...as are the values returned by the 'repeat with i in l' form of loop:
--------------
set l to {"one", "two", "three"}
set r to {}
repeat with i in l
set r's end to i
end repeat
r
--> {item 1 of {"one", "two", "three"}, item 2 of {"one", "two",
"three"}, item 3 of {"one", "two", "three"}}
--------------
As we've already discussed, in cases like the last 2, getting
dereferenced values requires some form of explicit coercion or use of
the 'contents of' operator. From this, I'd infer that the type of
reference has a bearing on how a variable is evaluated.
Your point about the 'is'/'is not' comparison operators (along with all
their syntactic variants) is also well taken. Given your comments about
the initial comparison of class (e.g: reference vs. integer), it's
hardly surprising that even an apparently exact match will return a
mismatch:
--------------
set l to {1, 2, 3, 4}
set r to {}
repeat with i in l
set r's end to i is 2
end repeat
r
--> {false, false, false, false}
--------------
The reasons for this seem logical enough. Silent, automatic coercions
in such a context might lead to unwanted or unexpected results - while
any explicit conversion will (hopefully) be entirely deliberate.
By contrast, other comparison operators ('is greater than', 'is less
than', 'is greater than or equal to', 'is less than or equal to', 'is
in', 'is contained by', etc...) evidently attempt an evaluation (as
required) before any comparison is made:
--------------
set l to {1, 2, 3, 4}
set r to {}
repeat with i in l
set r's end to i > 2
end repeat
r
--> {false, false, true, true}
--------------
Once again, it looks as if this is due to a silent coercion, allowing
an appropriate comparison to take place. For further evidence of this,
take the way in which number-string and string-string values are
compared:
--------------
set r to {}
repeat with v in {1, "1"}
set r's end to v > "02"
end repeat
r
--> {false, true}
--------------
The comparison apparently emulates some of the principles of
concatenation: In the first iteration, the value of the variable 'v' is
an integer (1). If the right-hand operand ("02") is coerced
accordingly, it will also become an integer (2), making the consequent
numerical comparison (1 > 2) false. During the second iteration, v is a
string ("1") - and so the text comparison ("1" > "02") would be true.
Anyway, that's pretty much what I assume to take place. Thanks for
bringing up this aspect of the subject - and apologies for a somewhat
lengthy response. At least you got me reflecting on it all. Then
again... just how sad is that on a Saturday night? ;-)
---
kai
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Applescript-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden