dkl
Full Member
Posts: 234
|
Post by dkl on Jan 27, 2022 1:45:33 GMT -5
Sometimes call/sub routines give me no end of problems! Below is an example. All I want to do is add a character to a string$ if it isn't already in the string. The first version (<< gosub>> routine) works fine. The second version (<< call/sub>> routine) doesn't work. I cannot see what I'm doing wrong or have missed out! I have to use the second way, as I am already in a call/sub routine in my programme I have tried adding an extra <<call assign byref sgrd$>> routine, but that didn't help. Perhaps, someone can see my glaring mistake? Thank you '<< gosub>> routine insert code here
Res$ = "g" [start] input z$ print "z$ -> ";z$ if Res$ = "g" or Res$ = "v" then gosub [checkIt] print "outside sub z$/sgrd$,pos -> ";z$,sgrd$,pos end if goto [start]
[checkIt] pos = instr(sgrd$,z$):if pos = 0 then sgrd$ = sgrd$ + z$ print "inside sub z$/sgrd$,pos -> ";z$,sgrd$,pos return '<< call/sub>> routine
Res$ = "g" global z$,sgrd$,pos [start] input z$ print "z$ -> ";z$ if Res$ = "g" or Res$ = "v" then call checkIt z$,sgrd$,pos print "outside sub z$/sgrd$,pos -> ";z$,sgrd$,pos end if goto [start]
sub checkIt z$,sgrd$,pos pos = instr(sgrd$,z$):if pos = 0 then sgrd$ = sgrd$ + z$ print "inside sub z$/sgrd$,pos -> ";z$,sgrd$,pos end sub
|
|
|
Post by Rod on Jan 27, 2022 2:40:37 GMT -5
Not at my pc just now but a couple of things to do. First is use the debugger. Click on the ladybug icon then in the debugger click on the left margin of the code pane at the first line in the sub. Run your program, it will stop at the checkpoint you created, now look at the variables.
First thing you should notice is that your variables aren’t there, why? Well you set them as global. Click to show all variables, check the contents.
I suspect you are confusing Liberty by creating global variables then passing them as arguments in the call.
The whole point of declaring something as global is to make it visible everywhere. So I think you need to stop doing that. Pass in local variables to the sub as arguments, use global variables on an exceptional basis inside a sub if required but don’t also pass them.
Get that sorted and see how you get on.
|
|
|
Post by metro on Jan 27, 2022 2:52:32 GMT -5
You already have a smarter coder on the job however, my observation is despite being declared Global I'm not sure pos is being seen as global. maybe that's not the issue but byref seems to help I input "q" and got back 6 in both inside and out
EDIT don't include pos in the call statement and it also works (remove it from the sub parameter too)
Res$ = "g" sgrd$="abcdeq" global z$,sgrd$,pos [start] input z$ print "z$ -> ";z$ if Res$ = "g" or Res$ = "v" then call checkIt z$,sgrd$,pos print "outside sub z$/sgrd$,pos -> ";z$,sgrd$,pos end if goto [start]
sub checkIt z$,sgrd$, byref pos pos = instr(sgrd$,z$):if pos = 0 then sgrd$ = sgrd$ + z$ print "inside sub z$/sgrd$,pos -> ";z$,sgrd$,pos
end sub
Res$ = "g" sgrd$="abcdeq" global z$,sgrd$,pos [start] input z$ print "z$ -> ";z$ if Res$ = "g" or Res$ = "v" then call checkIt z$,sgrd$ print "outside sub z$/sgrd$,pos -> ";z$,sgrd$,pos end if goto [start]
sub checkIt z$,sgrd$ pos = instr(sgrd$,z$):if pos = 0 then sgrd$ = sgrd$ + z$ print "inside sub z$/sgrd$,pos -> ";z$,sgrd$,pos
end sub
|
|
dkl
Full Member
Posts: 234
|
Post by dkl on Jan 27, 2022 4:12:18 GMT -5
Hi Metro and Rod, thank you for your time. Yes, Metro - 'pos' works with or without the global or byref, Note that the 2 print statements are different If you input a new character it will be added to the string sgrd$ - Inside The Sub, but Outside The Sub it is lost, so the string sgrd$ never changes, which is not what I want..................... OK, I've done a bit of fiddling! I only made sgrd$ global (I want it to be seen inside and outside the sub). I left 'pos' alone and declared z$ in the call/sub routine. That worked and I can add to the sgrd$ string$ without problems I'm still a bit confused as to what is going on. It won't work if I add sgrd$ to the call/sub and make it global as well. sgrd$ has to be made global and not mentioned in the initial call/sub. Anyhow, I've got it working, so thank you for pointing me in the right direction. I'll try to pay more attention to how I write these 'subs', Rod and hopefully I'll get the hang of them eventually! Have a good day/evening gentlemen:)
This was the final result
Res$ = "g" sgrd$="abcdeq" global sgrd$ [start] input z$ print "z$ -> ";z$ if Res$ = "g" or Res$ = "v" then call checkIt z$ print "outside sub z$/sgrd$,pos -> ";z$,sgrd$,pos end if goto [start]
sub checkIt z$ pos = instr(sgrd$,z$):if pos = 0 then sgrd$ = sgrd$ + z$ print "inside sub z$/sgrd$,pos -> ";z$,sgrd$,pos end sub
|
|
|
Post by tsh73 on Jan 27, 2022 4:51:55 GMT -5
Мe thinks then you use name of global variable as sub formal parameter like here
global a a=1 b=2 'not global
print call test4 b print "after calling sub ";b
sub test4 a 'use name of global var as a param name print "param in sub ";a a=a*10 print "param changed in a sub ";a end sub
parameter in code "shadows" global variable so while executing a sub it has no access to global variable. So changed value never reach global variable.
param in sub 2 param changed in a sub 20 after calling sub 2
|
|
|
Post by Rod on Jan 27, 2022 6:03:04 GMT -5
Just to add to tsh73 comment. When he says shadow what I think happens is that the parameters passed to the sub are created new within the sub. So by passing a global named variable you are creating two similarly named variables.
So Liberty gets confused. So simply don’t pass global variables. Don’t start thinking you need lots of global variables to make subs work.
That is the opposite of what you should be thinking. The point about subs is that you can name and use as many variables as you like being sure they will have no impact on the main program.
Quite often folks change the name of the variables passed. Pass it as z$ receive it as sz$ So it is clearer what’s in the sub and what’s in the main program.
If you find you need a main program variable in a sub, pass it rather than make it global.
|
|
|
Post by Carl Gundel on Jan 27, 2022 11:26:09 GMT -5
Just to add to tsh73 comment. When he says shadow what I think happens is that the parameters passed to the sub are created new within the sub. So by passing a global named variable you are creating two similarly named variables. So Liberty gets confused. So simply don’t pass global variables. Don’t start thinking you need lots of global variables to make subs work. That is the opposite of what you should be thinking. The point about subs is that you can name and use as many variables as you like being sure they will have no impact on the main program. Quite often folks change the name of the variables passed. Pass it as z$ receive it as sz$ So it is clearer what’s in the sub and what’s in the main program. If you find you need a main program variable in a sub, pass it rather than make it global. LB doesn't get confused, unless someone has found a bug in LB. If you name a parameter the same as a global, the SUB or FUNCTION will consider it to be a different variable from the global.
|
|
|
Post by Carl Gundel on Jan 27, 2022 12:04:00 GMT -5
First thing you should notice is that your variables aren’t there, why? Well you set them as global. Click to show all variables, check the contents. Yeah? That's interesting and looks like a problem with the debugger.
|
|
|
Post by Rod on Jan 27, 2022 12:22:01 GMT -5
Ok, agreed, the programmer gets confused
|
|
|
Post by tsh73 on Jan 27, 2022 13:00:38 GMT -5
Speaking of debugger problems. Why one can enter stuff into "execute" line (under the variables and above code) but cannot paste things there?
|
|
dkl
Full Member
Posts: 234
|
Post by dkl on Jan 27, 2022 17:17:58 GMT -5
Ah!.....that makes sense. Thank you
|
|