I am starting a little series on tips and tricks especially geared towards the beginner but possibly useful to more experienced users as well.
#1 Syntactic shortcuts for if statements
Instead of if (someVal.notNil) { do something } or if (someVal.isNil) { do something2 } we can use the syntactic shortcuts someVal !? { do something if the value is not nil } and someVal ?? { do something2 if the value is nil}. These are described in the Object help file. There is no syntactic shortcut for if (someval.notNil) { do something } { else do something2 } like eg. in JavaScript: someVal ? do something : do something2. Still the syntactic shortcuts are extremely helpful and add clarity to the code as I will try to demonstrate below:
// An event of events of events.... A very common and useful data structure which could easily be deeper than this. More on this in a later post.
// This is just a silly example
p = (sub: (sub2: (sub3: (val1: 6, val2: 8, val3: 7))))
// Now wanting to manipulate some values, but only if the sub-event is not nil and the values exist
// We can do this because the values exist
p.sub.sub2.sub3.newVal = p.sub.sub2.sub3.val1 * p.sub.sub2.sub3.val2 * p.sub.sub2.sub3.val3
// but this will throw an error because sub4 is not defined
p.sub.sub2.sub4.newVal = p.sub.sub2.sub4.val1 * p.sub.sub2.sub4.val2 * p.sub.sub2.sub4.val3
// So we need to safe-guard, first going for one-liners
if (p.sub.sub2.sub3.notNil) { p.sub.sub2.sub3.newVal = p.sub.sub2.sub3.val1 * p.sub.sub2.sub3.val2 * p.sub.sub2.sub3.val3 };
if (p.sub.sub2.sub4.notNil) { p.sub.sub2.sub4.newVal = p.sub.sub2.sub4.val1 * p.sub.sub2.sub4.val2 * p.sub.sub2.sub4.val3 };
/// pretty clumsy, so a 2 liner is better
(
var ev = p.sub.sub2.sub3;
if (ev.notNil) { ev.newVal = ev.val1 * ev.val2 * ev.val3 }
)
(
var ev = p.sub.sub2.sub4;
if (ev.notNil) { ev.newVal = ev.val1 * ev.val2 * ev.val3 }
)
// same result, p.sub.sub2.sub3.newVal = 336, p.sub.sub2.sub4 = nil;
// NOW USING SYNTACTIC SHORTCUTS we can get the best of both worlds: a 1 liner with the clarity of the 2 liner
p.sub.sub2.sub3 !? {|ev| ev.newVal = ev.val1 * ev.val2 * ev.val3 }
p.sub.sub2.sub4 !? {|ev| ev.newVal = ev.val1 * ev.val2 * ev.val3 }
// notice that the event, if not nil, is the argument to the function above unlike a normal if statement which has no arguments:
if (p.sub.sub2.sub3.notNil) {|ev| ev.debug(\ev) }
p.sub.sub2.sub3 !? {|ev| ev.debug(\ev) }
// If the values in the sub event are not guaranteed to exist we can again apply syntactic sugar for the nil check
p.sub.sub2.sub3 !? {|ev| ev.newVal = ev.val1 * ev.val2 * ev.val3 * (ev.val4 ? 1) }
// val4 is undefined so mulitply by 1 = no change
// if later we now define val4,
p = (sub: (sub2: (sub3: (val1: 6, val2: 8, val3: 7)))) // reset to original state
p.sub.sub2.sub3.val4 = 5;
p.sub.sub2.sub3 !? {|ev| ev.newVal = ev.val1 * ev.val2 * ev.val3 * (ev.val4 ? 1) }
// val4 is defined so multiply with val4 = 5;