Next:
Text::Wigwam::Library::System
Previous:
Text::Wigwam::Library::Sets
 [Table of Contents][Text::Wigwam Index]

Text::Wigwam::Library::Struct



NAME

Text::Wigwam::Library::Struct #adjoin, #join, #keys, #pop, #push, #reverse, #shift, #sizeof, #sort, #sort_keylist, #key_sort, #split, #substr, #unshift, #values

Description

This library provides directives that mostly deal with data structures.

Usage

The directives within this library can be imported into specific branches of the directive tree (which transcends from Text::Wigwam::Directives) via plug-ins or modules using one of the following techniques.

 package Text::Wigwam::Directives::some::arbitrary::branch;
 # import everything
 use Text::Wigwam::Library::Struct qw/:all/;

 package Text::Wigwam::Directives::another::arbitrary::branch;
 # import selectively
 use Text::Wigwam::Library::Struct qw(
  :adjoin
  :join
  :keys
  :pop
  :push
  :reverse
  :shift
  :sizeof
  :sort
  :sort_keylist
  :key_sort
  :split
  :substr
  :unshift
  :values
 );

Directives

#adjoin string hash|array macro|optional

Passes each key/value pair of hash|array through macro and joins the results of each call with string.

 [!!
  #adjoin ", "  %< one 1, two 2, three 3 > { #argv 0 '=' #argv 1 } 
  /* output (note that the order is arbitrary when adjoining hashes):
     two=2, one=1, three=3
  */
 !!]

If we omit the optional macro argument, or if the macro returns a null string, only the hash value is adjoined.

 [!!
    #adjoin ", "  %< one 1, two 2, three 3 >;
    /* output (arbitrary order):
       3, 1, 2
    */
 !!]

When adjoining arrays, the key represents a given value's index position within the array.

 [!!
   #adjoin "; " < zero one two three four > { #argv 0 '=' #argv 1 } 
   /* output:
      0=zero; 1=one; 2=two; 3=three; 4=four
   */
 !!]

If the optional macro argument is omitted, or if the macro returns a null string value, the array values are simply adjoined.

 [!!
   #adjoin "; " < zero one two three four >; 
   /* output:
      zero; one; two; three; four
   */
 !!]

The macro can be defined in advance and simply passed to the #adjoin directive when required.

 [!!
  #macro jmacro {
     #parameters < name value >
     name '=' value
  }
  #adjoin ", "  %< one 1, two 2, three 3 > jmacro 
  /* output (the order is arbitrary):
     three=3, one=1, two=2
  */
 !!]

#join string array

Returns a string made up of all elements of array, delimited by string.

 [!!
  #join ", " ( "a" "c" "e" "g" )
  /* output:  a, c, e, g */
 !!]

#keys array|hash

If a hash is provided, #keys returns an array containing all keys found in hash.

 [!!
  #join ", " #keys %< key1 val1, key2 val2 >
  /* output (the order will vary): key1, key2 */
 !!]

If an array is passed, #keys will return an array containing the indices of array.

 [!!
  #join ", " #keys ( "a" "b" "c" "d" )
  /* output:  0, 1, 2, 3 */
 !!]

#pop array

Removes the last element of array and returns its value. Consequently, array's size is decreased by one element.

 [!!
  #define array ( 1 2 3 4 5 )
  #while array #pop array
  /* output: 54321 */
 !!]

#push array arg

Adds an element to the end of array and sets its value to arg. Consequently, array's size is increased by one element. #push does not return a value.

 [!!
  #define array ( 1 2 3 )
  #push array 4
  #join ", " array
  /* output: 1, 2, 3, 4 */
 !!]

#reverse array|hash

If an array is provided, #reverse returns a copy of the elements contained within array in reverse order. array remains unaltered.

 [!!
  #join ", " #reverse ( 1 2 3 4 5 )
  /* output: 5, 4, 3, 2, 1 */
 !!]

If a hash is provided, #reverse returns a hash whose key/value pairs are reversed, with respect to hash. hash remains unaltered.

 [!!
  #join ", " #keys #reverse %( 1 2 3 4 5 6 )
  /* output (order will vary): 6, 4, 2 */
 !!]

#shift array

Removes the first element of array and returns its value. Consequently, the size of the array is decreased by one element, and all remaining elements within the array shift down one position.

 [!!
  #define array ( 1 2 3 4 5 )
  #while array #shift array
  /* output: 12345 */
 !!]

#sizeof arg

Returns the number of elements in arg, where arg is an array; numbers of keys where arg is a hash; or number of characters where arg is a string or scalar reference.

   hash size: [!! #sizeof %< a b c d > !!] (number of keys)
  array size: [!! #sizeof < a b c d > !!] (number of elements)
 scalar size: [!! #sizeof  "abcd" !!] (number of characters)
  macro size: [!! #sizeof #expr {} !!] (number of tokens)
 [!!
  /* output:
     hash size: 2 (number of keys)
    array size: 4 (number of elements)
   scalar size: 4 (number of characters)
    macro size: 2 (number of tokens)
  */
 !!]

#sort array

Returns a sorted copy of array elements taken from array, and array remains unaltered.

 [!!
  #join ", " #sort ( 02 6 1 7 10 "a" 4 "b" )
  /* output: 1, 02, 4, 6, 7, 10, a, b */
 !!]

As demonstrated in the previous example, the #sort directive takes true numeric values into account when sorting.

#key_sort key-list pattern-list

Returns an array of keys, supplied by the key-list argument, which are sorted according to the pattern-list, which is merely an ordered list of variables from whose values the keys are to be sorted. Each element of the pattern-list array represents a level of criteria to sort upon. Should the first element match two given entries, the second element will then be used and so on until a basis for sorting is found, or until all pattern criteria is exhausted, in which case the keys themselves serve as the final criteria.

The pattern-list elements take the following form:

 +path.to.keys.[:key].path:2.values

Optionally, the first character indicates the sort order: '+' indicates ascending; '-' indicates descending. If omitted, ascending is implied. The :key global represents the position within the path name where the keys will be inserted during the sort process.

The #key_sort directive is handy for sorting records which are stored in a nested hash complex, as the following examples demonstrate. First, we'll set up a mock inventory database...

 [!!
      #define inventory %<
         100001 %< onhand 10 price 19.95 item "Putty" >
         100002 %< onhand 10 price 19.95 item "Puppy" >
         100003 %< onhand 13 price 21.95 item "Clock" >
         100004 %< onhand 33 price 22.95 item "Pistol" >
         100005 %< onhand 12 price 14.99 item "Camera" >
         100006 %< onhand 21 price 16.99 item "Toaster" >
     >
 !!]

In Perl, this data structure would look something like this...

 $inventory = {
     100001 => { onhand => 30, price => "19.95", item => "Putty" },
     100002 => { onhand => 10, price => "19.95", item => "Puppy" },
     ...
 };

First, let's dump all of the records sorted by item field.

 [!! #foreach thing #key_sort inventory`keys ( "+inventory.[:key].item" ) !!>
     [!!thing!!] Qty: [!!inventory.[thing].onhand!!], 
     [!~ "$" inventory.[thing].price!!] ea. [!!inventory.[thing].item!!]
 <!!
  /* output:
     100005 Qty: 12, $14.99 ea. Camera
     100003 Qty: 13, $21.95 ea. Clock
     100004 Qty: 33, $22.95 ea. Pistol
     100002 Qty: 10, $19.95 ea. Puppy
     100001 Qty: 10, $19.95 ea. Putty
     100006 Qty: 21, $16.99 ea. Toaster
  */
 !!]

Next, let's list the items by quantity on-hand, beginning with the highest volume first.

 [!! #foreach thing #key_sort inventory`keys ( "-inventory.[:key].onhand" )!!>
     [!!thing!!] Qty: [!!inventory.[thing].onhand!!], 
     [!~ "$" inventory.[thing].price!!] ea. [!!inventory.[thing].item!!]
 <!!
  /* output:
     100004 Qty: 33, $22.95 ea. Pistol
     100006 Qty: 21, $16.99 ea. Toaster
     100003 Qty: 13, $21.95 ea. Clock
     100005 Qty: 12, $14.99 ea. Camera
     100002 Qty: 10, $19.95 ea. Puppy
     100001 Qty: 10, $19.95 ea. Putty
  */
 !!]

Finally, we'll sort the records by price, then by quantity on-hand in descending order, then by item name. Also, just because we can, we'll leave out the '+' this time on the criteria which we want sorted in ascending order.

 [!!
  #foreach thing #key_sort inventory`keys (
     "inventory.[:key].price"
     "-inventory.[:key].onhand"
     "inventory.[:key].item"
  )
  !!>
     [!!thing!!] Qty: [!!inventory.[thing].onhand!!],
     [!~ "$" inventory.[thing].price!!] ea. [!!inventory.[thing].item!!]
  <!~
  /* output:
     100005 Qty: 12, $14.99 ea. Camera
     100006 Qty: 21, $16.99 ea. Toaster
     100002 Qty: 10, $19.95 ea. Puppy
     100001 Qty: 10, $19.95 ea. Putty
     100003 Qty: 13, $21.95 ea. Clock
     100004 Qty: 33, $22.95 ea. Pistol
  */
 !!]

#sort_keylist is DEPRECATED - use #key_sort instead

Works like #key_sort, but the pattern-list elements take the following form:

 +path.to.keys.*.path:2.values

The asterisk character represents the position within the path name where the keys will be inserted during the sort process. This format was abandoned in favor of the globals-based format as implemented in the #key_sort directive.

#split separator string

Returns an array of elements made up of chunks of string separated by occurrences of separator.

 [!!
  #define array #split ":" "foo:bar:quux:bazz"
  #join ", " array
  /* output: foo, bar, quux, bazz */
 !!]

#substr string index num

Returns information in string after the numerically declared index which signifies the byte with which you wish to start the extraction. The amount of data returned will be limited to num bytes.

 [!!
  #substr "abcdefghijkl" 7 2
  /* output: hi */
 !!]

#unshift array arg

Inserts arg as the first element of array, thereby increasing the size of the array by one element, and moving all previously existing elements within the array up one position. #unshift does not return a value.

 [!!
  #define array ( 1 2 3 )
  #unshift array 4
  #join ", " array
  /* output: 4, 1, 2, 3 */
 !!]

#values hash

Returns an array of values found in hash.

 [!!
  #join ", " #values #hash ( "key1" "val1" "key2" "val2" )
  /* output (order will vary): val1, val2 */
 !!]