LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

Function-specific DEFs?

Root / Programming Questions / [.]

MariominerCreated:
I believe I asked once in chat -"Is it possible to have a DEF in a DEF?" I couldn't answer at that time a use for it, but now I have found one. I want to make a DEF that works inside of a DEF, but inside of only that one. Why? Because I want to be able to use local variables in it. But when it reads it, it uses global variables or says "Undefined variable". So I had to switch to using special global variables named for that function. Is there any way to accomplish the specific DEF, or should I just keep the system I have now? Or better yet, change to using GOSUBs and GOTOs?

As you probably know, you can't put one DEF block inside another (you get a 'Nested DEF' error). But you can call one function or command from inside another DEF block, and you're concerned about which variables the 'inner' command has access to - am I understanding that corrrectly? Let's say you define both CmdA and CmdB; if you call CmdB from within CmdA's DEF block, CmdB has access to both global variables and to any local variables inside the DEF CmdA block; moreover, in the case that there is a global variable and a local one with the same name, it chooses the local one from within the DEF CmdA block.
But when it reads it, it uses global variables or says "Undefined variable".
I'm getting different results than that. It will choose the local variable if there's both local and global of the same name. Probably this means I'm misunderstanding your question. If so, I apologize. EDIT: added strikethroughs, see below

CmdB has access to both global variables and to any local variables inside the DEF CmdA block;
Woah, that has interesting implications. I could bind class locals before every method call. EDIT: Except you have to accept the exact same arguments to the outer function as the inner... Before I knew about what BeautySoap just said, I would have said just use GOSUBS. They are in the same block, so the binding is obvious, and you can GOSUB ON.

Hold on, I'm probably wrong. I did some some testing and it looks like I made a false assumption about how it worked when designing my test - sorry about that. I don't think you have access to the local variables after all, just global ones.
...in the case that there is a global variable and a local one with the same name, ...
Yes, that's where I went wrong. You can't have local and global variables with the same name - if one with the same name appears inside a DEF block, it assume you meant the global one. I forgot about that when I tested before my previous post. Sorry to have gotten your hopes up.

Ok thats way more in line with like every other language's scoping.

Arrgh, I'm used to variables being local unless you declare them global. I keep forgetting that's not normal.

So now that I have my head on straight and remembered which language we're working in, getting back to Mariominer's question: As I mentioned, I'm not sure I understand your question correctly, but it seems you're concerned with controlling which variables the inner of two nested subroutines has access to. Variable access is exactly the issue that the concept of passing arguments was meant to address, and it seems like it would be easier to pass arguments to a DEF block than to use your suggestion of specially-named global variables. If you do switch over to GOTO/GOSUB, just remember to to use GOTO and not GOSUB inside a DEF block (if you were considering switching only your inner block).

Wait whats wrong with GOSUB in a DEF block?

It used to be that the RETURN at the end of the GOSUB block would exit the entire DEF block. Recently, another user has gotten different but equally undesirable results: http://smilebasicsource.com/forum?ftid=29 Amusingly, if you keep reading that thread after it wandered off topic twice, it also coincidentally happens to contain another shining example of me being wrong on the forums (about the same topic even, of variable globalization inside DEFs! You'd think I would have learned...) That's not related to the GOSUB-inside-DEF error, though.

Does GOSUB store the return address somewhere? Would using it in a DEF cause a memory leak?

You're trying to analyze what it is that causes that behavior? I'm not sure. Let us know what you find out. At least they acknowledge this one in the manual (although the manual doesn't call it a 'bug,' it just tells you not to use GOSUB or ON GOSUB inside a DEF). Oh, also, if Mariominer is considering redesigning his subroutine structure, it might also be good to point out here that when the manual says: "- GOTO outside the DEF to END range is impossible" ...they would appear to mean that if you use GOTO inside a DEF block, the label it goes to has to also be inside the DEF block.

another user has gotten different but equally undesirable results: http://smilebasicsource.com/forum?ftid=29
It is not a different result. Inside a DEF block, a GOTO will cause the program to continue executing at the specified point, and when it encounters a RETURN, the program will return from the DEF function/procedure. Inside a DEF block, a GOSUB will cause the program to continue executing at the specified point, and when it encounters a RETURN, the program will return from the DEF function/procedure (it does not RETURN to the GOSUB). As the title of the page says, "Inside DEF block, GOSUB is GOTO".

Hmm, thanks for the replies. I guess I might just keep it how it is now using globals as it works. Or maybe swap to GOTOs. Or GOSUBs. Either way.