Skip to main content
Question

Calling subroutines via '@var'

  • November 3, 2025
  • 5 replies
  • 85 views

rjo-au

Hello! I’m relatively new to UniVerse and Multi-valued databases, so my experience with BASIC is limited.

I was writing a program with subroutine calls that I wanted to abstract via ‘@<var>’. This program had a “create output file data line” subroutine and a “finalize output file” subroutine. When I wrote these local subroutines (explicitly defined, not subroutine labels), I encountered an error where, when calling with ‘@’, only the first locally-defined subroutine would be found; the other subroutine would cause a runtime error, unable to be located. It was not found locally, and so the object database file (.O) was being searched, instead.

For example:

* ...

IS.DONE = @FALSE

* Main loop
LOOP
READNEXT FILE.NAME ELSE
IS.DONE = @TRUE
END
UNTIL IS.DONE

* ...

OUPUT.FILE = ""
PREPARE.DATA.SUBR = ""
FINALIZE.FILE.SUBR = ""

* case 1
BEGIN CASE
CASE FILE.TYPE = TYPE.1
PREPARE.DATA.SUBR = "DO.SOMETHING.1"
FINALIZE.FILE.SUBR = "END.FILE.1"
CASE FILE.TYPE = TYPE.2
PREPARE.DATA.SUBR = "DO.SOMETHING.2"
FINALIZE.FILE.SUBR = "END.FILE.2"
CASE 1
* LOG ERROR
CONTINUE
END CASE

* ...

READ DATA.FILE FROM FILES, FILE.NAME ELSE
* HANDLE ERROR
END

DATA.LINE.COUNT = DCOUNT(DATA.FILE, @FM)
FOR LINE = 1 TO DATA.LINE.COUNT
DATA.LINE = DATA.FILE<LINE>


* ...


IF PREPARE.DATA.SUBR # "" THEN
CALL @PREPARE.DATA.SUBR(OUTPUT.FILE, DATA.LINE)
END
NEXT LINE


* ...


IF FINALIZE.FILE.SUBR # "" THEN
CALL @FINALIZE.FILE.SUBR(OUTPUT.FILE)
END


* ...
REPEAT; * End main loop

* program clean up
* ...

END; * program


* Subroutines *****************************************
* DO.SOMETHING.1 would be the only subroutine found, others
* called with @ will cause a runtime error



SUBROUTINE DO.SOMETHING.1(OUTPUT.FILE, DATA.LINE)

* ...

END; * DO.SOMETHING.1

SUBROUTINE DO.SOMETHING.2(OUTPUT.FILE, DATA.LINE)

* ...

END; * DO.SOMETHING.2

SUBROUTINE END.FILE.1(OUTPUT.FILE)

* ...

END; * END.FILE.1

SUBROUTINE END.FILE.2(OUTPUT.FILE)

* ...

END; * END.FILE.2

Calling the subroutines explicitly (with their actual name, i.e. ‘CALL DO.SOMETHING.1(...)’) did not result in runtime errors. Oddly enough, this error did not occur when testing with other, smaller programs. I was able to define two separate locally-defined subroutines and call them without runtime crashes.

I decided to go with explicit calls in this program to avoid any other issues, but I am curious as to why this had occurred in the first place.

Has anyone else encountered this behavior before and is able to explain what UniVerse does in the background to handle calls with ‘@<var>’? I understand that the search for the subroutines begins in the local/program scope and move outward towards the various catalogs, but is there more that I may be missing?

Thank you in advance to anyone able to help!

5 replies

John Jenkins
Forum|alt.badge.img+1
  • Participating Frequently
  • November 4, 2025

Rjo-ao,

 

UniVerse uses the @ prefix in BASIC to reference subrutines by name at run-time. For example@

If I use this construct at cimpilation time CALL MYSUB then object code for CALL MYSUB will br buit into the object program - hard coded and immutable.

If however I use this construct instead: CALL @expression then at runtime the expression is evaluated and the subroiutine of that name - as determined at runtime - is called. This allow the actual subroiutine name to be determined at runtime rather than beforehand in the source code.

Where would this be used? It depends on the use-case, but I’ve used it in general functional code where one or more variables control which different subroutines are invoked to perform a  runtime-dependent variant of a task. As an example - a subroutine to to encode virtual display/presentation  commmands to the display control sequences to achieve that on a specific slightly exotic terminal type  could be coded as:

VBS.DISP.ENCODE=”$VBS.DISP.ENCODE.”:$VBC.DISP.TYPE

CALL @VBS.DISP.ENCODE(argument)

So depending upon what presentation display type was selected at runtime, then a different encoding subroutine would be invoked while using the same contollign code for the functionality concerned..

 

While calling an @variable takes slightly longer than a direct reference, UniVerse attempts to compensate fr this.  When an @ variable is used in  a sibroutine CALL expression,  upon the very first CALL the text subroutine name in the variable is replaced by the address of the subroutine (just as if it bad been determined at compilation time). You can of course still change the content of the variable concerned to call a different subroutine  - which you could not do with a subroutine name determined at compile time.

Hoping this helps

​​​​​​​JJ


rjo-au
  • Author
  • New Participant
  • November 5, 2025

John,

That was my understanding of the ‘@VAR` feature, but thank you for your reply!

My issue came with having one of my local subroutines being unlocatable during runtime when calling said subroutine with ‘@VAR’. The subroutine exists in the object code when I used `VLIST`, but when I tried to call it in my program with ‘@VAR’, it can’t be found. This issue only affected subroutines defined after the first local subroutine; reordering the subroutine definitions would cause previously-called subroutines to also be unlocatable, but the first one can always be called. 

Do you know the specifics of how local subroutines are compiled alongside a UniVerse BASIC program (that is, subroutines defined in the same file as a BASIC program)? Maybe a way to debug to show the memory space of the program during runtime?

Thank you in advance!

Ray


John Jenkins
Forum|alt.badge.img+1
  • Participating Frequently
  • November 7, 2025

Rjo-au,

VLIST of the program may help in that regard - and using RAID to step through could show what happens to the variable data type and contents.

I suspect this will be one for Rocket support, but let;s see how far you can get - the more colalteral the better.

Regards

JJ

 


rjo-au
  • Author
  • New Participant
  • November 7, 2025

John,

VLIST showed the object code for the local subroutine being compiled, and when I ran RAID, the variable being used to call the local subroutine shared the same name (granted, I still have much to learn about this ecosystem).

Thank you again for your help! I’ll reach out to Rocket Support to see what they’re able to do to help. Thank you again!

If I find a solution to this problem, I’ll reply with a follow up detailing it, for anyone that might need it later on.

Thank you again, John!

Ray


Chris Charles

Hi rjo-au,

Have you tried replacing the ENDs for your subroutines with RETURN?