20,741
edits
(Created page with "{{Template:Nasal Navigation}} == Conditionals == Nasal has no "statements", which means that any expression can appear in any context. This means that you can use an if/els...") |
|||
| Line 149: | Line 149: | ||
var do_something = func return 0; | var do_something = func return 0; | ||
( a and do_something() ) or print("failed"); | ( a and do_something() ) or print("failed"); | ||
</syntaxhighlight> | |||
== Using Hashs to map keys to functions == | |||
You can easily reduce the complexity of huge conditional (IF) statements, such as this one: | |||
<syntaxhighlight lang="php"> | |||
if (a==1) function_a(); | |||
else | |||
if (a==2) function_b(); | |||
else | |||
if (a==3) function_c(); | |||
else | |||
if (a==4) function_d(); | |||
else | |||
if (a==5) function_e(); | |||
</syntaxhighlight> | |||
.. just by using the variable as a key (index) into a hash, so that you can directly call the corresponding function: | |||
<syntaxhighlight lang="php"> | |||
var mapping = {1:function_a, 2:function_b, 3:function_c, 4:function_d,5:function_e}; | |||
mapping[a] (); | |||
</syntaxhighlight> | |||
This initializes first a hash map of values and maps a function "pointer" to each value, so that accessing mapping[x] will return the function pointer for the key "x". | |||
Next, you can actually call the function by appending a list of function arguments (empty parentheses for no args) to the hash lookup. | |||
Using this technique, you can reduce the complexity of huge conditional blocks. For example, consider: | |||
# weather_tile_management.nas | |||
460 if (code == "altocumulus_sky"){weather_tiles.set_altocumulus_tile();} | |||
461 else if (code == "broken_layers") {weather_tiles.set_broken_layers_tile();} | |||
462 else if (code == "stratus") {weather_tiles.set_overcast_stratus_tile();} | |||
463 else if (code == "cumulus_sky") {weather_tiles.set_fair_weather_tile();} | |||
464 else if (code == "gliders_sky") {weather_tiles.set_gliders_sky_tile();} | |||
465 else if (code == "blue_thermals") {weather_tiles.set_blue_thermals_tile();} | |||
466 else if (code == "summer_rain") {weather_tiles.set_summer_rain_tile();} | |||
467 else if (code == "high_pressure_core") {weather_tiles.set_high_pressure_core_tile();} | |||
468 else if (code == "high_pressure") {weather_tiles.set_high_pressure_tile();} | |||
469 else if (code == "high_pressure_border") {weather_tiles.set_high_pressure_border_tile();} | |||
470 else if (code == "low_pressure_border") {weather_tiles.set_low_pressure_border_tile();} | |||
471 else if (code == "low_pressure") {weather_tiles.set_low_pressure_tile();} | |||
472 else if (code == "low_pressure_core") {weather_tiles.set_low_pressure_core_tile();} | |||
473 else if (code == "cold_sector") {weather_tiles.set_cold_sector_tile();} | |||
474 else if (code == "warm_sector") {weather_tiles.set_warm_sector_tile();} | |||
475 else if (code == "tropical_weather") {weather_tiles.set_tropical_weather_tile();} | |||
476 else if (code == "test") {weather_tiles.set_4_8_stratus_tile();} | |||
477 else ... | |||
While this is not a very complex or huge block of code, it is an excellent example for very good naming conventions used already, because the consistency of naming variables and functions can pay off easily here, with just some very small changes, you can already reduce the whole thing to a hash lookup like this: | |||
weather_tiles["set_"~code~"_tile"](); # naming convention | |||
This would dynamically concatenate a key consisting of "set_" + code + "_title" into the hash named weather_tiles, and then call the function that is returned from the hash lookup. | |||
So for this to work you only need to enforce consistency when naming your functions (i.e. this would of course CURRENTLY fail when the variable code contains "test" because there is no such hash member (it's "4_8_stratus" instead). | |||
The same applies to cumulus sky (fair weather), stratus/overcast stratus. | |||
But these are very simple changes to do (just renaming these functions to match the existing conventions). When you do that, you can easily replace such huge IF statements and replace them with a single hash lookup and function call: | |||
hash[key] (arguments...); | |||
For example, consider: | |||
<syntaxhighlight lang="php"> | |||
var makeFuncString = func(c) return tolower("set_"~c~"_tile"); | |||
var isFunc = func(f) typeof(f)=='func'; | |||
var hasMethod = func(h,m) contains(h,m) and isFunc; | |||
var callIfAvailable = func(hash, method, unavailable=func{} ) { | |||
var c=hasMethod(hash,makeFuncString(m) ) or unavailable(); | |||
hash[makeFuncString(m)] (); | |||
} | |||
callIfAvailable( weather_tiles,code, func {die("key not found in hash or not a func");} ); | |||
</syntaxhighlight> | </syntaxhighlight> | ||