How-to: Create and use a Batch file Function.

Packaging up code into a discrete functions, each with a clear purpose is a very common programming technique. Re-using known, tested code, means you can solve problems very quickly by just bolting together a few functions.

The CMD shell does not have any documented support for functions, but you can fake it by passing arguments/parameters to a subroutine and you can use SETLOCAL to control the visibility of variables.

A common first attempt at building a function:
:myfunct
SETLOCAL
SET _var1=%1
SET _var2="%_var1%--%_var1%--%_var1%"
SET _result=%_var2%
ENDLOCAL


but there is a problem, the ENDLOCAL command will throw away the _result variable and so the function returns nothing.

:myfunct2
SETLOCAL
SET _var1=%1
SET _var2="%_var1%--%_var1%--%_var1%"
ENDLOCAL
SET _result=%_var2%

This version is getting close, but it still fails to return a value, this time because ENDLOCAL will throw away the _var2 variable

The solution to this is to take advantage of the fact that the CMD shell evaluates variables on a line-by-line basis - so placing ENDLOCAL on the same line as the SET statement(s) gives the result we want. This technique is known as 'tunneling' and works for both functions and entire batch scripts:

:myfunct3
SETLOCAL
SET _var1=%1
SET _var2="%_var1%--%_var1%--%_var1%"
ENDLOCAL & SET _result=%_var2%


In examples above there are just 2 local variables (_var1 and _var2) but in practice there could be far more, by turning the script into a function with SETLOCAL and ENDLOCAL we don’t have to worry if any variable names will clash.

In other words you can do this, the variables _var1 and _var2 refer to completely different values inside and outside the subroutine:

@ECHO OFF
SET _var1=64
SET _var2=123
CALL :myfunct3 SomeText
echo _var1 is %_var1%
echo _var2 is %_var2%
echo Final result %_result%
goto :eof

:myfunct3
SETLOCAL
SET _var1=%1
SET _var2="%_var1%--%_var1%--%_var1%"
ENDLOCAL & SET _result=%_var2%

When working with functions it can be useful to use Filename Parameter Extensions against the function name, %0 will contain the call label, %~nx0 the file name, see Rob Hubbards blog for an example. Note that if you have two scripts one calling another, this will not reveal the location of the 'calling' script.

“A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works and cannot be patched up to make it work. You have to start over with a working simple system.” ~ John Gall (Gall’s Law)

Related commands

CALL - Call one batch program from another.
How-to: Macros - Embed blocks of code in a variable.
SETLOCAL - Control the visibility of environment variables.
SHIFT - Shift the position of replaceable parameters in a batch file.
DosTips.com - A collection of CMD functions.


 
Copyright © 1999-2024 SS64.com
Some rights reserved