1N/A
1N/AThe ability for users to define types has been added to ksh93t.
1N/AHere is a quick summary of how types are defined and used in ksh93t.
1N/AThis is still a work in progress so some changes and additions
1N/Aare likely.
1N/A
1N/AA type can be defined either by a shared library or by using the new
1N/Atypeset -T option to the shell. The method for defining types via
1N/Aa shared library is not described here. However, the source file
1N/Abltins/enum.c is an example of a builtin that creates enumeration types.
1N/A
1N/ABy convention, typenames begin with a capitol letter and end in _t.
1N/ATo define a type, use
1N/A typeset -T Type_t=(
1N/A definition
1N/A )
1N/Awhere definition contains assignment commands, declaration commands,
1N/Aand function definitions. A declaration command (for example typeset,
1N/Areadonly, and export), is a built-in that differs from other builtins in
1N/Athat tilde substitution is performed on arguments after an =, assignments
1N/Ado not have to precede the command name, and field splitting and pathname
1N/Aexpansion is not performed on the arguments.
1N/AFor example,
1N/A typeset -T Pt_t=(
1N/A float -h 'length in inches' x=1
1N/A float -h 'width in inches' y=0
1N/A integer -S count=0
1N/A len()
1N/A {
1N/A print -r $((sqrt(_.x*_.x + _.y*_.y)))
1N/A }
1N/A set()
1N/A {
1N/A (( _.count++))
1N/A }
1N/A )
1N/A
1N/Adefines a type Pt_t that has three variables x, y, and count defined as well
1N/Aas the discipline functions len and set. The variable x has an initial value
1N/Aof 1 and the variable y has an initial value of 0. The new -h option argument,
1N/Ais used for documentations purposes as described later and is ignored outside
1N/Aof a type definition.
1N/A
1N/A
1N/AThe variable count has the new -S attribute which means that it is shared
1N/Abetween all instances of the type. The -S option to typeset is ignored
1N/Aoutside of a type definition. Note the variable named _ that is used inside
1N/Athe function definition for len and set. It will be a reference to the
1N/Ainstance of Pt_t that invoked the function. The functions len and set
1N/Acould also have been defined with function len and function set, but
1N/Asince there are no local variables, the len() and set() form are more
1N/Aefficient since they don't need to set up a context for local variables
1N/Aand for saving and restoring traps.
1N/A
1N/AIf the discipline function named create is defined it will be
1N/Ainvoked when creating each instance for that type. A function named
1N/Acreate cannot be defined by any instance.
1N/A
1N/AWhen a type is defined, a declaration built-in command by this name
1N/Ais added to ksh. As with other shell builtins, you can get the man page
1N/Afor this newly added command by invoking Pt_t --man. The information from
1N/Athe -h options will be embedded in this man page. Any functions that
1N/Ause getopts to process arguments will be cross referenced on the generated
1N/Aman page.
1N/A
1N/ASince Pt_t is now a declaration command it can be used in the definition
1N/Aof other types, for example
1N/A typeset -T Rect_t=( Pt_t ur ll)
1N/A
1N/ABecause a type definition is a command, it can be loaded on first reference
1N/Aby putting the definition into a file that is found on FPATH.
1N/AThus, if this definition is in a file named Pt_t on FPATH, then
1N/Aa program can create instances of Pt_t without first including
1N/Athe definition.
1N/A
1N/AA type definition is readonly and cannot be unset. Unsetting non-shared
1N/Aelements of a type restores them to their default value. Unsetting a
1N/Ashared element has no effect.
1N/A
1N/AThe Pt_t command is used to create an instance of Pt_t.
1N/A Pt_t p1
1N/Acreates an instance named p1 with the initial value for p1.x set to 1
1N/Aand the initial value of p1.y set to 0.
1N/A Pt_t p2=(x=3 y=4)
1N/Acreates an instance with the specified initial values. The len function
1N/Agives the distance of the point to the origin. Thus, p1.len will output
1N/A1 and p2.len will output 5.
1N/A
1N/Aksh93t also introduces a more efficient command substitution mechanism.
1N/AInstead of $(command), the new command substitution ${ command;}
1N/Acan be used. Unlike (and ) which are always special, the { and } are
1N/Areserved words and require the space after { and a newline or ; before }.
1N/AUnlike $(), the ${ ;} command substitution executes the command in
1N/Athe current shell context saving the need to save and restore
1N/Achanges, therefore also allowing side effects.
1N/A
1N/AWhen trying to expand an element of a type, if the element does not exist,
1N/Aksh will look for a discipline function with that name and treat this as if
1N/Ait were the ${ ;} command substitution. Thus, ${p1.len} is equivalent to
1N/A${ p1.len;} and within an arithmetic expression, p1.len will be expanded
1N/Avia the new command substitution method.
1N/A
1N/AThe type of any variable can be obtained from the new prefix
1N/Aoperator @. Thus, ${@p1} will output Pt_t.
1N/A
1N/ABy default, each instance inherits all the discipline functions defined
1N/Aby the type definition other than create. However, each instance can define
1N/Aa function by the same name that will override this definition.
1N/AHowever, only discipline functions with the same name as those defined
1N/Aby the type or the standard get, set, append, and unset disciplines
1N/Acan be defined by each instance.
1N/A
1N/AEach instance of the type Pt_t behaves like a compound variable except
1N/Athat only the variables defined by the type can be referenced or set.
1N/AThus, p2.x=9 is valid, but p2.z=9 is not. Unless a set discipline function
1N/Adoes otherwise, the value of $p1 will be expanded to the form of a compound
1N/Avariable that can be used for reinput into ksh.
1N/A
1N/AIf the variables var1 and var2 are of the same type, then the assignment
1N/A var2=var1
1N/Awill create a copy of the variable var1 into var2. This is equivalent to
1N/A eval var2="$var1"
1N/Abut is faster since the variable does not need to get expanded or reparsed.
1N/A
1N/AThe type Pt_t can be referenced as if it were a variable using the name
1N/A.sh.type.Pt_t. To change the default point location for subsequent
1N/Ainstances of Pt_t, you can do
1N/A .sh.type.Pt_t=(x=5 y=12)
1N/Aso that
1N/A Pt_t p3
1N/A p3.len
1N/Awould be 13.
1N/A
1N/ATypes can be defined for simple variables as well as for compound
1N/Aobjects such as Pt_t. In this case, the variable named . inside
1N/Athe definition refers to the real value for the variable. For example,
1N/Athe type definition
1N/A typeset -T Time_t=(
1N/A integer .=0
1N/A _='%H:%M:%S'
1N/A get()
1N/A {
1N/A .sh.value=$(printf "%(${_._})T" "#$((_))" )
1N/A }
1N/A set()
1N/A {
1N/A .sh.value=$(printf "%(%#)T" "${.sh.value}")
1N/A
1N/A }
1N/A )
1N/A
1N/AThe sub-variable name _ is reserved for data used by discipline functions
1N/Aand will not be included with data written with the %B option to printf.
1N/AIn this case it is used to specify a date format.
1N/A
1N/AIn this case
1N/A Time_t t1 t2=now
1N/Awill define t1 as the time at the beginning of the epoch and t2
1N/Aas the current time. Unlike the previous case, $t2 will output
1N/Athe current time in the date format specified by the value t2._.
1N/AHowever, the value of ${t2.} will expand the instance to a form
1N/Athat can be used as input to the shell.
1N/A
1N/AFinally, types can be derived from an existing type. If the first
1N/Aelement in a type definition is named _, then the new type
1N/Aconsists of all the elements and discipline functions from the
1N/Atype of _ extended by elements and discipline functions defined
1N/Aby new type definition. For example,
1N/A
1N/A typeset -T Pq_t=(
1N/A Pt_t _
1N/A float z=0.
1N/A len()
1N/A {
1N/A print -r $((sqrt(_.x*_.x + _.y*_.y + _.z*_.z)))
1N/A }
1N/A )
1N/A
1N/Adefines a new type Pq_t which is based on Pq_t and contains an additional
1N/Afield z and a different len discipline function. It is also possible
1N/Ato create a new type Pt_t based on the original Pt_t. In this case
1N/Athe original Pt_t is no longer accessible.