Showing Submenus based on a condition, and timing of #if-#endif evaluation

I have trouble understanding the timing of #if statement evaluation. For example, try this code:

Function testit()
print Exists("root:test")
#if (Exists("root:test")==2)
     print "test"

If executed, the function will of course print 0. Now if I create a variable named test (Variable/G root:test=1), then the function will print 2 but not "test". If I edit the procedure code and recompile, then both 2 and "test" is printed. Does this mean the procedure where the code in question needs to be recompiled for the condition to be reevaluated? But then,


does not seem to update the function. I guess the reason is that above code only does something if the procedure is not compiled yet. Is there even a way from within the procedure code to reevaluate such conditional statements (like "Recompile")? 

Anyway, the reason for this somewhat obscure question is, that I want to make a submenu or a function appear on the condition that another procedure got loaded/included. The reason is that the code in question is mostly part of the procedure-to-load, and I don't want to have stuff floating around which may be confusing to users. The code I tried to use is something like:

#if (Exists("someOtherModule#FuncWithinModule")==6)
Menu "AnIgorMenu"
    Submenu "mySubmenu"
        "Do stuff", /Q, MyFunction()

Of course, this did not work well, both because of above problem, and probably because the compilation order of different procedures lets above Exist() statement fail. But even checking for some physical object like a wave is bound to fail if the procedure in question is not recompiled. Is there some other neat way to make submenus and their contents appear on some condition? By the way, I know very well that you could have a dynamic menu for a conditional appearance of menu items, but as far as I know there is nothing like this for whole menus / submenus including their contents. If there is no choice, then I guess I fall back to this option. I guess TLDR question is: How to re-evaluate #if-#endif code blocks after another procedure has been included.

Some time later... I remembered that one can, of course, show/hide menus with a dynamic text and "-". So part  of the initial question has been solved. But it would still be useful to know how #if-#else works exactly.

Additional question: Is it possible to have nested submenus (i.e., a submenu within a submenu)?

I've put the menu option within the someOtherModule directly. I've not been as brave as you appear to want to be to try to handle the cases where a module may get loaded and off-loaded manually by making the main package that should then include the menu have to do the checks behind.

What if its an official WM module? ;) Of course, I rather want to have menus in the right places directly (and so far this worked well). By the way, here is my solution:

Menu "someIgorMenu"
    Submenu myModule#CreateMenu()
        "DoStuff", /Q, DoStuffFunc()

static Function/S CreateMenu()
    return SelectString(Exists("someOtherModule#FuncWithinModule"),"-","mySubMenu")

Note: I don't declare the menu dynamic here, because menus are rebuilt anyway when the other module is loaded.

Follow-up: I was able to create nested submenus just fine. I was just being stupid. I am working on stuff which populates both the "TracePopup" and "GraphPopup" menus, but I forgot to copy the menu entries over. I didn't realize this and kept wondering why the menus did not appear.

While I don't need it anymore in my code, I would still be interested to hear more about the behavior of #if-#else.

The # in #if and friends indicates a compile option. It is only evaluated when that procedure file is compiled. If it is in an independent module, you may get surprising results, since the whole point of an IM is that it doesn't need to be recompiled just because some other file needs to be compiled.

Thanks for the description. I realized that such compile options are only useful to check some condition or state at start and not to adapt to changes while users are working in the experiment. I now work only with dynamic menu entries and Execute (to call possibly missing functions). Would have been nice to hide functions (from MPF ;) while things are not set up yet, but this is probably too fiddly. I guess all problems of this thread are solved now.

Not quite, but thank you for the hint. Good to know that something like this is possible. What I wanted to achieve is that a function is hidden from FunctionList() until things are set up (by preparing folders etc.). The reason you can see here:…

I wanted to hide DataPeak_PeakFuncInfo() from Multipeak Fit until things are set up. But it was only for cosmetic effect, so it is OK.