Setting values of Cocoa bindings recursively with a repeat loop?

Hi all,

I’m trying to significantly reduce the amount of code in an application that uses Cocoa bindings, and would like to know whether there is a possibility to update bound values within repeat loops. As an example, if my application’s UI has five NSTextFields bound to value1, […], value5, and I want to set each of these to “defaultValue” is there a way of getting the kind of code below to work?

repeat with theItem in {value1, value2, value3, value4, value5} --values are Cocoa bindings
	set my theItem to defaultValue
end repeat

The above code gives me the error:


Thanks in advance for your help!

Max

I’d guess you want something more like:

repeat with theItem in {my value1, my value2, my value3, my value4, my value5} --values are Cocoa bindings
   set theItem to defaultValue
end repeat

I don’t know how ASOC behaves but consider that in vanilla AppleScript you can’t change a value of a property by
indirect referencing

in a normal list (no properties) this code doesn’t change the value of a list item


set theList to {1, 2, 3}
repeat with theItem in theList
	set theItem to 4
end repeat
theList --> {1, 2, 3}

you have to deference explicitly the list item


set theList to {1, 2, 3}
repeat with theItem in theList
	set the contents of theItem to 4
end repeat
theList --> {4, 4, 4}

this changes the values in the list theList, but not the property values


property value1 : 0
property value2 : 1
property value3 : 2

set theList to {value1, value2, value3}
repeat with theItem in theList
	set contents of theItem to 4
end repeat
theList --> {4, 4, 4}
value1 --> 0

nor this


property value1 : 0
property value2 : 1
property value3 : 2

set theList to {a reference to value1, a reference to value2, a reference to value3}
repeat with theItem in theList
	set contents of theItem to 4
end repeat
theList --> {4, 4, 4}
value1 --> 0

nor this


property value1 : 0
property value2 : 1
property value3 : 2

set theList to {my value1, my value2, my value3}
repeat with theItem in theList
	set contents of theItem to 4
end repeat
theList --> {4, 4, 4}
value1 --> 0

To save code lines you could use


set {my value1, my value2, my value3, my value4, my value5} to {defaultValue, defaultValue, defaultValue, defaultValue, defaultValue}

You can do it by making your list a list of setters for those values, and then using performSelector_withObject: In ASOC, selectors are strings, and the (implied) setter for value1 is setValue1: (notice the capital “V” and the colon). So, this will work:

set theList to {"setValue1:", "setValue2:", "setValue3:"}
        repeat with anItem in theList
            performSelector_withObject_(anItem,defaultValue)
        end repeat

Ric

Thank you all!

Shane, your code does not update the bound values, for the reasons explained by Stefan.
I decided to implement the solution that rdelmar suggested, and it works great.
I think I’m gonna be able to get my application to work with about 4 times less code!

Thanks again for your help!

Max

actually in vanilla applescript this does the trick!

property value1 : 0

property value2 : 1

property value3 : 2

set theList to {a reference to value1, a reference to value2, a reference to value3}
repeat with theitem in theList
set contents of contents of theitem to 4
end repeat
log theList → (4, 4, 4)
log value1 ->(4)

What I really like about this solution is that I can reduce my code even further by creating the strings of theList within the repeat loop.

Originally my code was:

set my selectedVoice1 to defaultValue
set my selectedVoice2 to defaultValue
set my selectedVoice3 to defaultValue
set my selectedVoice4 to defaultValue
set my selectedVoice5 to defaultValue
set my selectedVoice6 to defaultValue 

With rdelmar’s solution I got the code down to:

repeat with theItem in {"setSelectedVoice1:", "setSelectedVoice2:", "setSelectedVoice3:", "setSelectedVoice4:", "setSelectedVoice5:", "setSelectedVoice6:"}
	performSelector_withObject_(theItem,defaultVoice)
end repeat

And creating the strings of the list within the repeat loop makes the code even shorter and easier to maintain:

repeat with i from 1 to 6
	set theItem to "setSelectedVoice" & i & ":"
	performSelector_withObject_(theItem, defaultVoice)
end repeat