Description of problem: When used in a function, typeset should always create a local instance of its variables. It is failing to do this. Version-Release number of selected component (if applicable): fc6 package ksh-20060214-1.1 How reproducible: typeset a variable in a function and display that variable on return from the function. The variable should not contain the value set in the function. Steps to Reproduce: ---------------------------------------------------------------- x1: #!/bin/ksh F1 () { typeset T1 T1="Wrong!" } echo "Before=$T1" F1 echo "After=$T1" ---------------------------------------------------------------- Actual results: /bin/ksh ./x1 Before= After=Wrong! Expected results: /bin/ksh ./x1 Before= After= Additional info:
From the ksh man page: For historical reasons, there are two ways to define functions, the name() syntax and the function name syntax, ... (...) Functions defined with the name() syntax and functions defined with the function name syntax that are invoked with the . special built-in are executed in the caller’s environment and share all variables and traps with the caller. So if you try the following, you'll see the difference: #!/bin/ksh F1 () { typeset T1 T1="Wrong!" } function F2 { typeset T2 T2="Right" } echo "Before=$T1" F1 echo "After=$T1" echo "Before=$T2" F2 echo "After=$T2" This is a documented and expected behaviour. Do you agree?
First off, I find the man page description that you have quoted to be confusing. It appears to say that functions defined either way are handled the same. If there is a difference between the definition forms, making the man page clearer would be a good thing. But, in any case, I disagree that this is the documented or expected behavior. The man page also states: "However, the typeset special built-in command used within a function defines local variables whose scope includes the current function." In my mind, this is the primary use of typeset. In any case, typeset should certainly not act differently depending on how the function was declared. Think for a moment about a function containing a statement like: typeset -r IFS=':' Under this ksh, this function could only be called once (subsequent calls would error on redefinition of a readonly variable) and worse yet, you've now permenantly defined IFS for the entire script. Even without the -r, the whole point is to make that instance of IFS local to the function. typeset correctly makes the variable local in *all other* versions of ksh I work with, regardless of which syntax is used to define the function. This includes the ones packaged with: aix, tru64, solaris, and hpux. It also has the correct behavior in pdksh (packaged with many linux distros including RHEL4) and with all versions of bash.
The manpage part you cite is about functions defined with function keyword... You may also want to read 'typeset --man'. I really don't see anything "wrong" on the behaviour. The "all other versions" you mentioned are all ksh88 implementations -- FC6 comes with ksh93.
I'm still not sure I'm totally on-board here. It is not clear that the System V Release 2 semantics of 'name ()' would prohibit typeset from making a variable local. I agree that the description of typeset in the Functions section of the man93 page is contained within the paragraph dealing with the 'function name' definition. However, both ways to define a function share all variables (by default) and the paragraph describing 'name ()' does not specify the behavior of typeset. Furthermore, the man93 definition of the typeset builtin says: "When invoked inside a function, a new instance of the variable vname is created. The variable's value and type are restored when the function completes." There is no qualification here for typeset to work differently, based on which syntax was used to define the function or anything else. If Posix really intended to disable the functionality of typeset for 'name ()' functions, that would be a really stupid thing for them to have done! If they didn't, then ksh should be fixed. If they did, then the man page describing the typeset builtin is wrong. Either way, something needs to be fixed here. I'm hoping it's the former.
POSIX doesn't say anything about typeset. It only says that function is defined: fname() compound-command[io-redirect ...] where compound-command is (compound-list) => the compound-list is executed in subshell environment or {compound-list} => the compound-list is executed in current environment The later is our case and that's why any variable (no matter how defined) is visible in the caller's environment. And ksh93 works exactly according to the specification (unlike ksh88). Man page in ksh-20060214-1.1 says "When invoked inside a function defined with the function name syntax, a new instance of the variable vname is created...". I'm sorry -- I still don't see anything that should be fixed.
It looks like POSIX really was just stupid here. Considering a "typeset name" to be a NO-OP in "fname ()" functions is a very bad decision. The only reason a script writer would put "typeset name" into a function is to make name a local variable. To disregard the script writer's explicit command for no good reason is at best extremely irritating. In any case, I now consider this bug to be a documentation bug. As quoted above, the typeset builtin claims it always creates a local variable (without exception). The documentation should be amended to state that while it always does this in "function fname" functions, that it never does this in "fname ()" functions.
I went through the documentation and it's quite clear (I have quoted the disputable part of 'man ksh' in the comment #5). I don't consider this to be even a documentation issue.