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