ksh: Decide what to do about the unknown `getn` discipline
I just discovered that, contrary to all the documentation, ksh understands not four initial kinds of discipline functions, but five. There is an undocumented getn
discipline: https://github.com/ksh93/ksh/blob/3f8add41482147bfa5595281c878953068e33c68/src/cmd/ksh93/data/variables.c#L111
I’ve experimentally found that the getn
discipline is like get
, but for arithmetic expressions. For instance, for $foo
, the discipline function foo.get
is called, but for $((foo))
(with no dollar sign before foo
), the discipline function foo.getn
is called (with no fallback to (edit: yeah, that’s wrong, see further below). This is not documented anywhere and I cannot even find a single mention on Google.foo.get
if foo.getn
is not defined)
$ foo.get() { echo GET; }
$ foo.getn() { echo GETN; }
$ : $foo
GET
$ : $((foo))
GETN
$ : $(($foo))
GET
A search in the ast-open-archive repo reveals that the getn
discipline was quietly added in version 2009-08-21 93t+.
Annoyingly, there is no corresponding distinction for the set
discipline. There is no setn
discipline and the foo.set
discipline function is called for both foo=bar
and ((foo=1337))
.
So, there are some things for the community to consider. Here are my views:
I think it’s a bug thatfoo.get
is not called for$((foo))
. It’s contrary to all the documentation to date, which says thatfoo.get
is called if thefoo
variable is referenced. Referencing it in an arithmetic expression without a preceding dollar sign is still referencing it.I think it’s wrong that$((foo))
and$(($foo))
call different disciplines. These expansions should be and are widely assumed to be equivalent. (See also 5da8eb31b32ced429017db534e5f6961c4cf7b7b)
So I think we should remove It’s not even used in any of the other AST code in ast-open-archive, regression tests included. If anyone can find a trace of prior use, that might change things.getn
and make arithmetic expressions call get
instead. I don’t think backwards compatibility is a major concern here as getn
is completely undocumented and no one seems to have discovered it before me.
On the other hand, if we decide to keep and document getn
, perhaps we should introduce a corresponding setn
and make ksh call foo.setn
instead of foo.set
for $((foo))
. But that would be a greater compatibility concern as the current behaviour of the set
discipline is widely known and documented.
Or we could change nothing and just document the current situation. It does not seem to be possible to introduce consistency without introducing some incompatibility or another.
I tend to put a high priority on consistency, so all things considered, removing .getn
and folding it into get
seems to be the lesser evil to me
Thoughts, opinions?
About this issue
- Original URL
- State: open
- Created 2 years ago
- Comments: 16
Commits related to this issue
- Fix crash on setting attribute to variable with getn discipline The 'getn' discipline is experimental and undocumented, the only mention of it being an old mailing list post from David Korn: https://... — committed to ksh93/ksh by McDutchie 2 years ago
- Fix crash on setting attribute to variable with getn discipline The 'getn' discipline is experimental and undocumented, the only mention of it being an old mailing list post from David Korn: https://... — committed to ksh93/ksh by McDutchie 2 years ago
- [v1.0] Remove experimental .getn discipline *.getn discipline functions cause .sh.value to have a float type for arithmetic expressions that get the value of foo, avoiding the problem of having to co... — committed to ksh93/ksh by McDutchie 2 years ago
Considering that:
setn
discipline was never implemented),I now think it’s best to just get rid of the whole thing.
I’m also not actually convinced this is the best design. Defining additional disciplines will confuse most users and a correct usage in scripts will be the exception rather than the rule.
The problem it was meant to solve could be perhaps be solved in a different way. In the normal
get
andset
disciplines,.sh.value
could inherit any integer/float typeset attributes of the parent variable, which would fix the string conversion problem. But that’s a project for a post-1.0 release.The following thread on the old mailing list seems relevant: https://www.mail-archive.com/ast-users@research.att.com/msg00601.html