Home > atmlab > handy > prstnt_struct.m

prstnt_struct

PURPOSE ^

PRSTNT_STRUCT Handles a persistent structure.

SYNOPSIS ^

function [A,value] = prstnt_struct( A, def_fun, varargin )

DESCRIPTION ^

 PRSTNT_STRUCT   Handles a persistent structure.

    This a help function to handle the setting and extraction of fields
    values of a structure, defined as persistent in some function. 

    A persistent structure can be used for several purposes. The application
    in mind here is that the structure contains a number of settings of 
    global type. How this function works is best described by an example.
    Let's say that we want to have a function that tells various plotting 
    function what color map to use, without having that as input to each 
    function. We create then a function called *cmap* with a local
    sub-function *cmap_def*:

       function value = cmap( varargin )
         persistent A
         [A,value] = prstnt_struct( A, @cmap_def, varargin );
       
       function A = cmap_def
         A.map = 'gray';

    By executing 
       map = cmap('map'); 
    we get the present setting for the color map. A new color map is set as 
       cmap('map','jet');"
    The existing fields and their values are returned by
       cmap;
    The default settings are re-created by:
       cmap('defaults');
    That fields exist and are not NaN can be performed as:
       cmap('require', {'map','dummy'} );
    where in this case an error will occur as the field 'dummy' does not 
    exist.

    This is a very simple example. The technique is of course more powerful
    if more settings variables are involved.

    More fields are added to the structure by adding a definition in the 
    function setting the default values. It is not allowed to add fields
    not defined in the default function.

    If the structure will contain large variables it could be worth the
    effort to copy the code of this function (with some modifications) to 
    the function where the persistent structure is defined to avoid un-
    necassary copying of data.

 FORMAT   [A,value] = prstnt_struct( A, def_fun, varargin )
        
 OUT   A          The structure.
       value      Extracted value (if applicable, otherwise []).
 IN    A          The structure.
       def_func   Handle to function setting default values for fields.
       varargin   The input to the calling function.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

DOWNLOAD ^

prstnt_struct.m

SOURCE CODE ^

0001 % PRSTNT_STRUCT   Handles a persistent structure.
0002 %
0003 %    This a help function to handle the setting and extraction of fields
0004 %    values of a structure, defined as persistent in some function.
0005 %
0006 %    A persistent structure can be used for several purposes. The application
0007 %    in mind here is that the structure contains a number of settings of
0008 %    global type. How this function works is best described by an example.
0009 %    Let's say that we want to have a function that tells various plotting
0010 %    function what color map to use, without having that as input to each
0011 %    function. We create then a function called *cmap* with a local
0012 %    sub-function *cmap_def*:
0013 %
0014 %       function value = cmap( varargin )
0015 %         persistent A
0016 %         [A,value] = prstnt_struct( A, @cmap_def, varargin );
0017 %
0018 %       function A = cmap_def
0019 %         A.map = 'gray';
0020 %
0021 %    By executing
0022 %       map = cmap('map');
0023 %    we get the present setting for the color map. A new color map is set as
0024 %       cmap('map','jet');"
0025 %    The existing fields and their values are returned by
0026 %       cmap;
0027 %    The default settings are re-created by:
0028 %       cmap('defaults');
0029 %    That fields exist and are not NaN can be performed as:
0030 %       cmap('require', {'map','dummy'} );
0031 %    where in this case an error will occur as the field 'dummy' does not
0032 %    exist.
0033 %
0034 %    This is a very simple example. The technique is of course more powerful
0035 %    if more settings variables are involved.
0036 %
0037 %    More fields are added to the structure by adding a definition in the
0038 %    function setting the default values. It is not allowed to add fields
0039 %    not defined in the default function.
0040 %
0041 %    If the structure will contain large variables it could be worth the
0042 %    effort to copy the code of this function (with some modifications) to
0043 %    the function where the persistent structure is defined to avoid un-
0044 %    necassary copying of data.
0045 %
0046 % FORMAT   [A,value] = prstnt_struct( A, def_fun, varargin )
0047 %
0048 % OUT   A          The structure.
0049 %       value      Extracted value (if applicable, otherwise []).
0050 % IN    A          The structure.
0051 %       def_func   Handle to function setting default values for fields.
0052 %       varargin   The input to the calling function.
0053 
0054 % 2002-12-14   Created by Patrick Eriksson.
0055 
0056 
0057 function [A,value] = prstnt_struct( A, def_fun, varargin )
0058 
0059 
0060 rqre_nargin( 3, nargin );
0061 
0062 
0063 if isempty( A )
0064   A = feval( def_fun );
0065 end
0066 
0067 
0068 %=== As this function is called with a varargin argument, we have to extract
0069 %=== varargin as given to the calling function.
0070 %
0071 varg = varargin{1};
0072 
0073 
0074 value = [];
0075 
0076 switch length( varg )
0077 
0078   case 0
0079     %
0080     value = A;
0081 
0082   case 1
0083     %
0084     if strcmp( varg{1}, 'defaults' )
0085       A = feval( def_fun );
0086  
0087     else
0088 
0089       if ~isfield( A, varg{1} )
0090           error('atmlab:input:undefined', ...
0091             'The field %s is not defined', varg{1}); 
0092       end
0093 
0094       value = getfield( A, varg{1} );
0095 
0096     end
0097 
0098 
0099   case 2
0100 
0101     if strcmp( varg{1}, 'require' )
0102       for i = 1 : length(varg{2})
0103         if ~isfield( A, varg{2}{i} )
0104           error('atmlab:input','\nThe field %s is required.\n\n', varg{2}{i}); 
0105         end
0106         if isnan( getfield( A, varg{2}{i} ) )
0107           error('atmlab:input:undefined' ,...
0108               'The field %s is required but is NaN.\n\n', varg{2}{i} ); 
0109         end
0110       end
0111 
0112     else
0113       if ~isfield( A, varg{1} )
0114           error('atmlab:input:undefined' ,...
0115               'The field %s is not defined.', varg{1} );
0116       end
0117 
0118       value = getfield( A, varg{1} );
0119       
0120       A = setfield( A, varg{1}, varg{2} );
0121 
0122     end
0123 
0124   otherwise
0125     %
0126     error('atmlab:input','Too many input arguments.');
0127 end

Generated on Mon 15-Sep-2014 13:31:28 by m2html © 2005