In the course of migrating from pdksh to ksh93 we came across several problems
with functions:
1. Modifying the function definition file / modifying FPATH
Executing a function from FPATH apparently loads a bytecode version and a
reference to the source code. Once the source file is changed, typeset –f
<name> typically shows a corrupt definition, however, ksh93 still executes the
original version. I wonder whether this behavior is intended.
cp003421_home> unset -f modfunc
cp003421_home> FPATH=$STD_FPATH:$TESTDIR
cp003421_home> modfunc
original version
Called without arg f
cp003421_home> typeset -f modfunc
function modfunc {
echo "original version"
if [[ $1 = f ]]; then
echo "Called with arg f"
else
echo "Called without arg f"
fi
}
cp003421_home> echo "modfunc definition file modified"
modfunc definition file modified
cp003421_home> typeset -f modfunc # corrupt modified definition without
closing brace
function modfunc {
echo "2. modified version"
if [[ $1 = f ]]; then
echo "Called with arg f"
else
echo "Called without arg f"
fi
cp003421_home> modfunc # original version
original version
Called without arg f
cp003421_home> FPATH=$STD_FPATH
cp003421_home> modfunc
-ksh: modfunc: not found [No such file or directory]
cp003421_home> typeset -f modfunc
cp003421_home> FPATH=$STD_FPATH:$TESTDIR
cp003421_home> typeset -f modfunc # currently unknown
cp003421_home> modfunc # again original version although in the meantime “not
found”
original version
Called without arg f
cp003421_home> typeset -f modfunc # previous corrupt definition without
closing brace
function modfunc {
echo "2. modified version"
if [[ $1 = f ]]; then
echo "Called with arg f"
else
echo "Called without arg f"
fi
cp003421_home>
2. Redefining a function known in the calling context inside another function
When testing ksh93 with function definitions inside functions, we have detected
an undocumented difference in behavior between calling the function directly
and inside a $(…) construct. When calling the function directly, an identically
named function in the calling context is overwritten in any case, inside a $(…)
construct the local function redefinition is ignored unless you include a
typeset -f <funcname> >/dev/null, the /dev/null redirection is essential.
cp003421_utils> typeset -f common_func
common_func() { echo "Global function"; }
cp003421_utils> . ./testfunc;. ./testfuncu;. ./testfuncut;. ./testfunct;.
./testfunctn
cp003421_utils> typeset -f testfunc testfuncu testfuncut testfunct testfunctn
function testfunc {
typeset LOCALVAR=1
#unset -f common_func
#typeset -f common_func
common_func () { echo "Local function"; }
if [[ $1 = f ]]; then
common_func
else
echo "Local script body"
fi
}
function testfuncu {
typeset LOCALVAR=1
unset -f common_func
#typeset -f common_func
common_func () { echo "Local function"; }
if [[ $1 = f ]]; then
common_func
else
echo "Local script body"
fi
}
function testfuncut {
typeset LOCALVAR=1
unset -f common_func
typeset -f common_func
common_func () { echo "Local function"; }
if [[ $1 = f ]]; then
common_func
else
echo "Local script body"
fi
}
function testfunct {
typeset LOCALVAR=1
#unset -f common_func
typeset -f common_func
common_func () { echo "Local function"; }
if [[ $1 = f ]]; then
common_func
else
echo "Local script body"
fi
}
function testfunctn {
typeset LOCALVAR=1
#unset -f common_func
typeset -f common_func >/dev/null
common_func () { echo "Local function"; }
if [[ $1 = f ]]; then
common_func
else
echo "Local script body"
fi
}
cp003421_utils> for func in testfunc testfuncu testfuncut testfunct testfunctn;
do
> echo -n ${func}:; echo $($func f)
> typeset -f common_func
> done
testfunc:Global function
common_func() { echo "Global function"; }
testfuncu:Global function
common_func() { echo "Global function"; }
testfuncut:common_func() { echo "Global function"; } Global function
common_func() { echo "Global function"; }
testfunct:common_func() { echo "Global function"; } Global function
common_func() { echo "Global function"; }
testfunctn:Local function
common_func() { echo "Global function"; }
cp003421_utils> for func in testfunc testfuncu testfuncut testfunct testfunctn;
do
> common_func() { echo "Global function"; }
> unset -f $func
> . ./$func
> echo -n ${func}:; $func f
> typeset -f common_func
> done
testfunc:Local function
common_func() { echo "Local function"; }
testfuncu:/bin/ksh[5]: testfuncu[11]: common_func: not found [No such file or
directory]
common_func() { echo "Local function"; }
testfuncut:/bin/ksh[5]: testfuncut[11]: common_func: not found [No such file or
directory]
common_func() { echo "Local function"; }
testfunct:common_func() { echo "Global function"; }
Local function
common_func() { echo "Local function"; }
testfunctn:Local function
common_func() { echo "Local function"; }
Using the third type of command substitution ${ list;} gives an even more
unconventional behavior:
cp003421_utils> unset -f testfunc common_func
cp003421_utils> common_func() { echo "Global function"; }
cp003421_utils> . ./testfunc
cp003421_utils> typeset -f testfunc
function testfunc {
typeset LOCALVAR=1
#unset -f common_func
#typeset -f common_func
common_func () { echo "Local function"; }
if [[ $1 = f ]]; then
common_func
else
echo "Local script body"
fi
}
cp003421_utils> echo ${ testfunc f;}
Global function
cp003421_utils> typeset -f common_func
common_func() { echo "Local function"; }
cp003421_utils> echo ${ testfunc f;}
Global function
testfunc uses the global function, changes the definition in the calling
context, but continues to use the original global definition.
The behavior of testfunctn if called in the $(...) context is IMO the desired
behavior for a function defined in the function name syntax.
Mit freundlichen Gruessen / Best Regards
Axel PHILIPP
Dr. rer. nat., Dipl. Phys.
MTU Aero Engines AG
Informationswirtschaft/Entwicklungssysteme (FIE)
Information Management/Engineering Systems (FIE)
Dachauer Str. 665
80995 Muenchen
Germany
--
MTU Aero Engines AG
Geschaeftsfuehrung/Board of Management: Egon W. Behle, Vorsitzender/CEO; Dr.
Rainer Martens, Michael Schreyögg, Dr. Stefan Weingartner, Reiner Winkler
Vorsitzender des Aufsichtsrats/Chairman of the Supervisory Board: Klaus
Eberhardt
Sitz der Gesellschaft/Registered Office: Muenchen
Handelsregister/Commercial Register: Muenchen HRB 157206
Diese E-Mail sowie ihre Anhaenge enthalten MTU-eigene vertrauliche oder
rechtlich geschuetzte Informationen.
Wenn Sie nicht der beabsichtigte Empfaenger sind, informieren Sie bitte den
Absender und loeschen Sie diese
E-Mail sowie die Anhaenge. Das unbefugte Speichern, Kopieren oder Weiterleiten
ist nicht gestattet.
This e-mail and any attached documents are proprietary to MTU, confidential or
protected by law.
If you are not the intended recipient, please advise the sender and delete this
message and its attachments.
Any unauthorised storing, copying or distribution is prohibited.
_______________________________________________
ast-users mailing list
[email protected]
http://lists.research.att.com/mailman/listinfo/ast-users