1*b30d1939SAndy Fiddaman 2*b30d1939SAndy FiddamanThe ability for users to define types has been added to ksh93t. 3*b30d1939SAndy FiddamanHere is a quick summary of how types are defined and used in ksh93t. 4*b30d1939SAndy FiddamanThis is still a work in progress so some changes and additions 5*b30d1939SAndy Fiddamanare likely. 6*b30d1939SAndy Fiddaman 7*b30d1939SAndy FiddamanA type can be defined either by a shared library or by using the new 8*b30d1939SAndy Fiddamantypeset -T option to the shell. The method for defining types via 9*b30d1939SAndy Fiddamana shared library is not described here. However, the source file 10*b30d1939SAndy Fiddamanbltins/enum.c is an example of a builtin that creates enumeration types. 11*b30d1939SAndy Fiddaman 12*b30d1939SAndy FiddamanBy convention, typenames begin with a capitol letter and end in _t. 13*b30d1939SAndy FiddamanTo define a type, use 14*b30d1939SAndy Fiddaman typeset -T Type_t=( 15*b30d1939SAndy Fiddaman definition 16*b30d1939SAndy Fiddaman ) 17*b30d1939SAndy Fiddamanwhere definition contains assignment commands, declaration commands, 18*b30d1939SAndy Fiddamanand function definitions. A declaration command (for example typeset, 19*b30d1939SAndy Fiddamanreadonly, and export), is a built-in that differs from other builtins in 20*b30d1939SAndy Fiddamanthat tilde substitution is performed on arguments after an =, assignments 21*b30d1939SAndy Fiddamando not have to precede the command name, and field splitting and pathname 22*b30d1939SAndy Fiddamanexpansion is not performed on the arguments. 23*b30d1939SAndy FiddamanFor example, 24*b30d1939SAndy Fiddaman typeset -T Pt_t=( 25*b30d1939SAndy Fiddaman float -h 'length in inches' x=1 26*b30d1939SAndy Fiddaman float -h 'width in inches' y=0 27*b30d1939SAndy Fiddaman integer -S count=0 28*b30d1939SAndy Fiddaman len() 29*b30d1939SAndy Fiddaman { 30*b30d1939SAndy Fiddaman print -r $((sqrt(_.x*_.x + _.y*_.y))) 31*b30d1939SAndy Fiddaman } 32*b30d1939SAndy Fiddaman set() 33*b30d1939SAndy Fiddaman { 34*b30d1939SAndy Fiddaman (( _.count++)) 35*b30d1939SAndy Fiddaman } 36*b30d1939SAndy Fiddaman ) 37*b30d1939SAndy Fiddaman 38*b30d1939SAndy Fiddamandefines a type Pt_t that has three variables x, y, and count defined as well 39*b30d1939SAndy Fiddamanas the discipline functions len and set. The variable x has an initial value 40*b30d1939SAndy Fiddamanof 1 and the variable y has an initial value of 0. The new -h option argument, 41*b30d1939SAndy Fiddamanis used for documentations purposes as described later and is ignored outside 42*b30d1939SAndy Fiddamanof a type definition. 43*b30d1939SAndy Fiddaman 44*b30d1939SAndy Fiddaman 45*b30d1939SAndy FiddamanThe variable count has the new -S attribute which means that it is shared 46*b30d1939SAndy Fiddamanbetween all instances of the type. The -S option to typeset is ignored 47*b30d1939SAndy Fiddamanoutside of a type definition. Note the variable named _ that is used inside 48*b30d1939SAndy Fiddamanthe function definition for len and set. It will be a reference to the 49*b30d1939SAndy Fiddamaninstance of Pt_t that invoked the function. The functions len and set 50*b30d1939SAndy Fiddamancould also have been defined with function len and function set, but 51*b30d1939SAndy Fiddamansince there are no local variables, the len() and set() form are more 52*b30d1939SAndy Fiddamanefficient since they don't need to set up a context for local variables 53*b30d1939SAndy Fiddamanand for saving and restoring traps. 54*b30d1939SAndy Fiddaman 55*b30d1939SAndy FiddamanIf the discipline function named create is defined it will be 56*b30d1939SAndy Fiddamaninvoked when creating each instance for that type. A function named 57*b30d1939SAndy Fiddamancreate cannot be defined by any instance. 58*b30d1939SAndy Fiddaman 59*b30d1939SAndy FiddamanWhen a type is defined, a declaration built-in command by this name 60*b30d1939SAndy Fiddamanis added to ksh. As with other shell builtins, you can get the man page 61*b30d1939SAndy Fiddamanfor this newly added command by invoking Pt_t --man. The information from 62*b30d1939SAndy Fiddamanthe -h options will be embedded in this man page. Any functions that 63*b30d1939SAndy Fiddamanuse getopts to process arguments will be cross referenced on the generated 64*b30d1939SAndy Fiddamanman page. 65*b30d1939SAndy Fiddaman 66*b30d1939SAndy FiddamanSince Pt_t is now a declaration command it can be used in the definition 67*b30d1939SAndy Fiddamanof other types, for example 68*b30d1939SAndy Fiddaman typeset -T Rect_t=( Pt_t ur ll) 69*b30d1939SAndy Fiddaman 70*b30d1939SAndy FiddamanBecause a type definition is a command, it can be loaded on first reference 71*b30d1939SAndy Fiddamanby putting the definition into a file that is found on FPATH. 72*b30d1939SAndy FiddamanThus, if this definition is in a file named Pt_t on FPATH, then 73*b30d1939SAndy Fiddamana program can create instances of Pt_t without first including 74*b30d1939SAndy Fiddamanthe definition. 75*b30d1939SAndy Fiddaman 76*b30d1939SAndy FiddamanA type definition is readonly and cannot be unset. Unsetting non-shared 77*b30d1939SAndy Fiddamanelements of a type restores them to their default value. Unsetting a 78*b30d1939SAndy Fiddamanshared element has no effect. 79*b30d1939SAndy Fiddaman 80*b30d1939SAndy FiddamanThe Pt_t command is used to create an instance of Pt_t. 81*b30d1939SAndy Fiddaman Pt_t p1 82*b30d1939SAndy Fiddamancreates an instance named p1 with the initial value for p1.x set to 1 83*b30d1939SAndy Fiddamanand the initial value of p1.y set to 0. 84*b30d1939SAndy Fiddaman Pt_t p2=(x=3 y=4) 85*b30d1939SAndy Fiddamancreates an instance with the specified initial values. The len function 86*b30d1939SAndy Fiddamangives the distance of the point to the origin. Thus, p1.len will output 87*b30d1939SAndy Fiddaman1 and p2.len will output 5. 88*b30d1939SAndy Fiddaman 89*b30d1939SAndy Fiddamanksh93t also introduces a more efficient command substitution mechanism. 90*b30d1939SAndy FiddamanInstead of $(command), the new command substitution ${ command;} 91*b30d1939SAndy Fiddamancan be used. Unlike (and ) which are always special, the { and } are 92*b30d1939SAndy Fiddamanreserved words and require the space after { and a newline or ; before }. 93*b30d1939SAndy FiddamanUnlike $(), the ${ ;} command substitution executes the command in 94*b30d1939SAndy Fiddamanthe current shell context saving the need to save and restore 95*b30d1939SAndy Fiddamanchanges, therefore also allowing side effects. 96*b30d1939SAndy Fiddaman 97*b30d1939SAndy FiddamanWhen trying to expand an element of a type, if the element does not exist, 98*b30d1939SAndy Fiddamanksh will look for a discipline function with that name and treat this as if 99*b30d1939SAndy Fiddamanit were the ${ ;} command substitution. Thus, ${p1.len} is equivalent to 100*b30d1939SAndy Fiddaman${ p1.len;} and within an arithmetic expression, p1.len will be expanded 101*b30d1939SAndy Fiddamanvia the new command substitution method. 102*b30d1939SAndy Fiddaman 103*b30d1939SAndy FiddamanThe type of any variable can be obtained from the new prefix 104*b30d1939SAndy Fiddamanoperator @. Thus, ${@p1} will output Pt_t. 105*b30d1939SAndy Fiddaman 106*b30d1939SAndy FiddamanBy default, each instance inherits all the discipline functions defined 107*b30d1939SAndy Fiddamanby the type definition other than create. However, each instance can define 108*b30d1939SAndy Fiddamana function by the same name that will override this definition. 109*b30d1939SAndy FiddamanHowever, only discipline functions with the same name as those defined 110*b30d1939SAndy Fiddamanby the type or the standard get, set, append, and unset disciplines 111*b30d1939SAndy Fiddamancan be defined by each instance. 112*b30d1939SAndy Fiddaman 113*b30d1939SAndy FiddamanEach instance of the type Pt_t behaves like a compound variable except 114*b30d1939SAndy Fiddamanthat only the variables defined by the type can be referenced or set. 115*b30d1939SAndy FiddamanThus, p2.x=9 is valid, but p2.z=9 is not. Unless a set discipline function 116*b30d1939SAndy Fiddamandoes otherwise, the value of $p1 will be expanded to the form of a compound 117*b30d1939SAndy Fiddamanvariable that can be used for reinput into ksh. 118*b30d1939SAndy Fiddaman 119*b30d1939SAndy FiddamanIf the variables var1 and var2 are of the same type, then the assignment 120*b30d1939SAndy Fiddaman var2=var1 121*b30d1939SAndy Fiddamanwill create a copy of the variable var1 into var2. This is equivalent to 122*b30d1939SAndy Fiddaman eval var2="$var1" 123*b30d1939SAndy Fiddamanbut is faster since the variable does not need to get expanded or reparsed. 124*b30d1939SAndy Fiddaman 125*b30d1939SAndy FiddamanThe type Pt_t can be referenced as if it were a variable using the name 126*b30d1939SAndy Fiddaman.sh.type.Pt_t. To change the default point location for subsequent 127*b30d1939SAndy Fiddamaninstances of Pt_t, you can do 128*b30d1939SAndy Fiddaman .sh.type.Pt_t=(x=5 y=12) 129*b30d1939SAndy Fiddamanso that 130*b30d1939SAndy Fiddaman Pt_t p3 131*b30d1939SAndy Fiddaman p3.len 132*b30d1939SAndy Fiddamanwould be 13. 133*b30d1939SAndy Fiddaman 134*b30d1939SAndy FiddamanTypes can be defined for simple variables as well as for compound 135*b30d1939SAndy Fiddamanobjects such as Pt_t. In this case, the variable named . inside 136*b30d1939SAndy Fiddamanthe definition refers to the real value for the variable. For example, 137*b30d1939SAndy Fiddamanthe type definition 138*b30d1939SAndy Fiddaman typeset -T Time_t=( 139*b30d1939SAndy Fiddaman integer .=0 140*b30d1939SAndy Fiddaman _='%H:%M:%S' 141*b30d1939SAndy Fiddaman get() 142*b30d1939SAndy Fiddaman { 143*b30d1939SAndy Fiddaman .sh.value=$(printf "%(${_._})T" "#$((_))" ) 144*b30d1939SAndy Fiddaman } 145*b30d1939SAndy Fiddaman set() 146*b30d1939SAndy Fiddaman { 147*b30d1939SAndy Fiddaman .sh.value=$(printf "%(%#)T" "${.sh.value}") 148*b30d1939SAndy Fiddaman 149*b30d1939SAndy Fiddaman } 150*b30d1939SAndy Fiddaman ) 151*b30d1939SAndy Fiddaman 152*b30d1939SAndy FiddamanThe sub-variable name _ is reserved for data used by discipline functions 153*b30d1939SAndy Fiddamanand will not be included with data written with the %B option to printf. 154*b30d1939SAndy FiddamanIn this case it is used to specify a date format. 155*b30d1939SAndy Fiddaman 156*b30d1939SAndy FiddamanIn this case 157*b30d1939SAndy Fiddaman Time_t t1 t2=now 158*b30d1939SAndy Fiddamanwill define t1 as the time at the beginning of the epoch and t2 159*b30d1939SAndy Fiddamanas the current time. Unlike the previous case, $t2 will output 160*b30d1939SAndy Fiddamanthe current time in the date format specified by the value t2._. 161*b30d1939SAndy FiddamanHowever, the value of ${t2.} will expand the instance to a form 162*b30d1939SAndy Fiddamanthat can be used as input to the shell. 163*b30d1939SAndy Fiddaman 164*b30d1939SAndy FiddamanFinally, types can be derived from an existing type. If the first 165*b30d1939SAndy Fiddamanelement in a type definition is named _, then the new type 166*b30d1939SAndy Fiddamanconsists of all the elements and discipline functions from the 167*b30d1939SAndy Fiddamantype of _ extended by elements and discipline functions defined 168*b30d1939SAndy Fiddamanby new type definition. For example, 169*b30d1939SAndy Fiddaman 170*b30d1939SAndy Fiddaman typeset -T Pq_t=( 171*b30d1939SAndy Fiddaman Pt_t _ 172*b30d1939SAndy Fiddaman float z=0. 173*b30d1939SAndy Fiddaman len() 174*b30d1939SAndy Fiddaman { 175*b30d1939SAndy Fiddaman print -r $((sqrt(_.x*_.x + _.y*_.y + _.z*_.z))) 176*b30d1939SAndy Fiddaman } 177*b30d1939SAndy Fiddaman ) 178*b30d1939SAndy Fiddaman 179*b30d1939SAndy Fiddamandefines a new type Pq_t which is based on Pq_t and contains an additional 180*b30d1939SAndy Fiddamanfield z and a different len discipline function. It is also possible 181*b30d1939SAndy Fiddamanto create a new type Pt_t based on the original Pt_t. In this case 182*b30d1939SAndy Fiddamanthe original Pt_t is no longer accessible. 183