The Unwind-on-Undefined Behaviour
If you're using format expression like {director} or {vc} you may have noticed that if a variable is not defined, it will cause the entire {expression} to fail and unwind.A common issue when writing expressions like this [{vc}, {ac}] is that it might evaluate to [, ] if the required bindings are undefined. A better way would be to write {"$vc, $ac"} (as String) or {[vc, ac]} (as List) in which case this single expression will only work if all required bindings are defined.
This expression will either evaluate successfully as a single unit, or fail as a single unit:
Format: Select all
{"A ${director} Movie"}
Format: Select all
{"A ${throw new Exception()} Movie"}
Format: Select all
{"A ${self.director} Movie"}
Format: Select all
{"A ${null} Movie"} // A null Movie
Format: Select all
{"A ${self.director ?: 'No Name'} Movie"}
Helper Functions
FileBot adds a few simple functions that can make your code much more easy to read if you need to collect the values of multiple bindings/expressions that may or may not fail and unwind.any(Closure...)
Find and return the value of the first expression that evaluates successfully without returning null or throwing an Exception. If none of the expressions evaluates successfully null will be returned.
e.g. Take collection, or if collection is undefined take the first genre, or if no genres are defined use a fixed String value:
Format: Select all
{ any{ collection }{ genre }{ 'No collection or Genre' } }
Find and return all values of all the expressions that evaluate successfully and ignore all expressions that fail or unwind.
e.g. Take the values of multiple bindings and simply ignore those that are undefined:
Format: Select all
{ allOf{ fn.match(/Extended.Edition/) }{ vc }{ ac }{ hdr }{ source }{ group }.join('.') }
Check if each expression yields a negative result of fails to yield a result altogether.
e.g. Return true if none of the given expressions yield a positive result:
Groovy: Select all
none{ ext =~ /jpg|png/ }{ fn.match(/sample|trailer/) }
Real-World Examples
e.g. combine binding variable and separator literals into a single {expression} so that you get either all or nothing (e.g. ".10bit" or ".HDR" but never just ".") and don't end up with superfluous separator literals:Format: Select all
{ ny.colon(' - ') }{ '-' + vf }{ '.' + bitdepth + ' bit' }{ '.' + hdr }{ '-' + group }
Format: Select all
{ any{ vs }{ width >= 1280 ? 'BluRay' : 'DVD' } }
Format: Select all
{ any{ certification }{ 'NR' } }
Format: Select all
{ any{ 'Season ' + s.pad(2) }{ 'Specials' } }
Format: Select all
{ drive }/Media/{ plex.id % { allOf{ vf }{ hdr }.joining(' ', ' [', ']') } }