coding functions and subroutines

#1
I am unsure of how to call a function that is too long to define as a normal 1 or 2 line function. Any help appreciated...

rem subroutine definition:
:: -----------------------------------------------------------------------
:SelectPathForType[sFile]
:: -----------------------------------------------------------------------

rem main subroutine
:: -----------------------------------------------------------------------
:MyMain
:: -----------------------------------------------------------------------


do sFile in /P dir /a:-d /f /s /h %sPathSourceHeap
echo %sFile
set [email protected]%SelectPathForType[%sFile]
iff "%sPathSubDir" NE "N/P" then
call MyMove[%aPathTargetBase,%aPathSubDir,%sFile,%nMaxJPGFilesinFolder]
endiff
enddo

:: -----------------------------------------------------------------------
:MyMove[aPathTargetBase, aPathSubDir, sFile, nMaxFilesIfJPG]
:: -----------------------------------------------------------------------
 
May 20, 2008
457
2
#2
In the code above, your @% should be reversed. It should be %@SelectPathForType.

If you just want to define a function for one BTM, an easy way is like this:
Code:
function SelectPathForType=%@execstr[gosub SelectPathForType %1]
set sPathSubDir=%@SelectPathForType[%sFile]
...
goto end

:SelectPathForType [file]
... do stuff
echo %result
return

:end
If you want the function to be used by more than one BTM or at the command line, you could either add the "filename" parameter to the gosub or use the ^ line continuation character as a normal multi-line function.
 
#3
I don't see any functions there ... only a subroutine. There should be a space between the subroutine name and arg list.
Code:
:SelectPathForType [file]
and it should be called like this
Code:
gosub SelectPathForType file
If you really want to use a function, @SetPathForType[], it needs to be defined with a FUNCTION command.

I don't think you can call a subroutine with the @NAME[] syntax. (Did I miss something?) There are tricks for getting more than one "line" into a function. Here's one such trick. Below, the SET will be executed but have no effect on the function @foo.

Code:
v:\> function foo `%@exec[@set xx=yy]%@upper[%1]`

v:\> echo %@foo[abc]
ABC

v:\> set xx
yy[CODE]
 
#4
So I can have a function with the same name as a label? I'll attach the BTM to this message.....

In the code above, your @% should be reversed. It should be %@SelectPathForType.

If you just want to define a function for one BTM, an easy way is like this:
Code:
function SelectPathForType=%@execstr[gosub SelectPathForType %1]
set sPathSubDir=%@SelectPathForType[%sFile]
...
goto end

:SelectPathForType [file]
... do stuff
echo %result
return

:end
If you want the function to be used by more than one BTM or at the command line, you could either add the "filename" parameter to the gosub or use the ^ line continuation character as a normal multi-line function.
 

Attachments

#5
Charles, I think you have subroutines and functions mixed up. Your BTM defines a subroutine named SelectPathForType. AFAIK there must be a space after that name and before the names of it's parameters:
Code:
:SelectPathForType [sFile]
You use the subroutine by calling it with GOSUB, like this.
Code:
gosub SelectPathForType %sFile
And a subroutine cannot return a string (as in your "return sPathNew"). A subroutine can only return a number, and that number will be in the _? variable if you wanted to test it.

So simply call the subroutine as I suggested.
Code:
gosub SelectPathForType %sFile
Let it end with a simple
Code:
return
and when you get back to MyMain, sPathNew will be set (because the subroutine set it) and you just

Code:
set sPathSubDir=sPathNew
or have the subroutine set sPathSubDir instead of sPathNew in the first place.

The %@ syntax is for functions, which are created with the FUNCTION command. I doubt you'll get all that stuff in the SelectPathForType subroutine into a function. Here's a dumb example of function usage.
Code:
v:\> function MyFunction `%@left[2,%@upper[%1]]`

v:\> echo %@MyFunction[foo]
FO
 
May 20, 2008
457
2
#9
Sorry for the delay. Here's a version of the file that uses internal functions. It reported incorrect function until I put the "." around the "or". To test locally, I also stripped down the do and commented out the move and del.
 

Attachments

May 20, 2008
457
2
#10
Forgot to set this: the functions should also have backticks:
Code:
function SelectPathForType=`%@execstr[gosub SelectPathForType %1]`
function SpecialCase=`%@execstr[gosub SpecialCase %1]`