Documentation

This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English verison of the page.

Note: This page has been translated by MathWorks. Please click here
To view all translated materals including this page, select Japan from the country navigator on the bottom of this page.

Code Patterns for subsref and subsasgn Methods

Customize Indexed Reference and Assignment

User-defined classes have the same indexing behaviors as that of built-in classes. Classes can customize indexing operations by overloading the functions that MATLAB® calls to evaluate indexing expressions. Overload the subsref and subsasgn functions when you want to define special behaviors for indexed reference and assignment.

For an overview of object indexing, see Object Array Indexing.

Syntax for subsref and subsasgn Methods

MATLAB calls the subsref and subsasgn methods of your class with these arguments.

MethodInputOutput

b = subsref(obj,s)

  • obj — Object or object array used in indexing expression

  • s — Indexing structure

b — Result of indexing expression

obj = subsasgn(obj,s,b)

  • obj — Object or object array used in indexing expression

  • s — Indexing structure

  • b — Value being assigned

obj — Object or object array after assignment

Modifying Number of Arguments

If your class design requires that indexing operations return or assign a different number of values than the number defined by the default indexing operation, overload the numArgumentsFromSubscript function to control nargout for subsref and nargin for subsasgn. For more information and examples, see numArgumentsFromSubscript.

Indexing Structure Describes Indexing Expressions

The indexing structure contains information that describes the indexing expression. Class methods use the information in the indexing structure to evaluate the expression and implement custom behavior.

For example, the CustomIndex class defines a property that you can use in indexing expressions.

classdef CustomIndex
   properties
      DataArray
   end
end

Create an object and assign a 5-by-5 matrix created by the magic function to the DataArray property.

a = CustomIndex;
a.DataArray = magic(5);

This subscripted reference expression returns the first row of the 5-by-5 matrix.

a.DataArray(1,:)
ans =

    17    24     1     8    15

This expression assigns new values to the first row of the array stored in the DataArray property.

a.DataArray(1,:) = [1 2 3 4 5];

This assignment statement uses:

  • A '.' type reference

  • A property name following the dot (that is, DataArray)

  • A range of indices (1,:) within parentheses

The indexing structure contains this information in the type and subs fields.

Values of the Indexing Structure

When executing an indexing expression, MATLAB calls the class subsref or subsasgn method, if the class overloads these functions. One of the arguments passed to the method is the indexing structure. The indexing structure has two fields:

  • type — One of the three possible indexing types: '.', '()', '{}'

  • subs — A char vector with the property name or cell array of the indices used in the expression, including : and end.

If the indexing expression is a compound expression, then MATLAB passes an array of structures, one struct for each level of indexing. For example, in this expression:

a.DataArray(1,:)

the indexing structure array S has these values:

  • S(1).type is set to '.', indicating that the first indexing operation is a dot.

  • s(1).subs is set to the property name, 'DataArray'

The second level of indexing is in the second element of the indexing structure:

  • S(2).types is set to '()' indicating the second indexing operation is parentheses indexing

  • S(2).subs is set to a cell array containing the indices {[1],[:]}

Typical Patterns for Indexing Methods

To overload the subsref and subasgn functions:

  • Determine the full indexing expression using the types and subs fields of the indexing structure.

  • Implement the specialized behaviors for the indexing operations supported by the class.

  • Return the appropriate values or modified objects in response to the call by MATLAB.

A switch statement is a convenient way to detect the first level of indexing. There are three types of indexing—dot, parentheses, and braces. Each case block in the switch statement implements all indexing expressions that begin with that first-level type of indexing.

The methods must implement all indexing expressions that the class supports. If you do not customize a particular type of indexing, call the built-in function to handle that expression.

Use the length of the indexing structure array and indexing type define conditional statements for compound indexing expressions.

Code Framework for subsref Method

The following framework for the subsref method shows how to use information in the indexing structure in conditional statements. Your application can involve other expression not shown here.

function varargout = subsref(obj,s)
   switch s(1).type
      case '.'
         if length(s) == 1
            % Implement obj.PropertyName
            ...
         elseif length(s) == 2 && strcmp(s(2).type,'()')
            % Implement obj.PropertyName(indices)
            ...
         else
            varargout = {builtin('subsref',obj,s)};
         end
      case '()'
         if length(s) == 1
            % Implement obj(indices)
            ...
         elseif length(s) == 2 && strcmp(s(2).type,'.')
            % Implement obj(ind).PropertyName
            ...
         elseif length(s) == 3 && strcmp(s(2).type,'.') && strcmp(s(3).type,'()')
            % Implement obj(indices).PropertyName(indices)
            ...
         else
            % Use built-in for any other expression
            varargout = {builtin('subsref',obj,s)};
         end
      case '{}'
         if length(s) == 1
            % Implement obj{indices}
            ...
         elseif length(s) == 2 && strcmp(s(2).type,'.')
            % Implement obj{indices}.PropertyName
            ...
         else
            % Use built-in for any other expression
            varargout = {builtin('subsref',obj,s)};
         end
      otherwise
         error('Not a valid indexing expression')
   end

Using varargout for the returned value enables the method to work with object arrays. For example, suppose that you want to support the return of a comma-separated list with an expression like this one:

[x1,...xn] = objArray.PropertyName(Indices)

This expression results in a two-element indexing structure array. The first-level type is dot ('.') and the second level is parentheses ('()'). Build the varargout cell array with each value in the array.

case '.'
   ...
   if length(s)==2 && strcmp(s(2).type,'()')
      prop = s(1).subs;      % Property name
      n = numel(obj);        % Number of elements in array
      varargout = cell(1,n); % Preallocate cell array
      for k = 1:n
         varargout{k} = obj(k).(prop).(s(2).subs);
      end
   end
   ...
end

subsasgn Pattern

The following framework for the subsasgn method shows how to use the indexing structure in conditional statements that implement assignment operations.

function obj = subsasgn(obj,s,varargin)
   switch s(1).type
      case '.'
         if length(s) == 1
            % Implement obj.PropertyName = varargin{:};
            ...
         elseif length(s) == 2 && strcmp(s(2).type,'()')
            % Implement obj.PropertyName(indices) = varargin{:};
            ...
         else
            % Call built-in for any other case
            obj = builtin('subsasgn',obj,s,varargin);
         end
      case '()'
         if length(s) == 1
            % Implement obj(indices) = varargin{:};
         elseif length(s) == 2 && strcmp(s(2).type,'.')
            % Implement obj(indices).PropertyName = varargin{:};
            ...
         elseif length(s) == 3 && strcmp(s(2).type,'.') && strcmp(s(3).type,'()')
            % Implement obj(indices).PropertyName(indices) = varargin{:};
            ...
         else
            % Use built-in for any other expression
            obj = builtin('subsasgn',obj,s,varargin);
         end       
      case '{}'
         if length(s) == 1
            % Implement obj{indices} = varargin{:}
            ...
         elseif length(s) == 2 && strcmp(s(2).type,'.')
            % Implement obj{indices}.PropertyName = varargin{:}
            ...
            % Use built-in for any other expression
            obj = builtin('subsasgn',obj,s,varargin);
         end
      otherwise
         error('Not a valid indexing expression')
   end
end

Using varargin for the right-side value of the assignment statement enables the method to work with object arrays. For example, suppose that you want to support the assignment of a comma-separated list with an expression like this one:

C = {'one';'two','three'};
[objArray.PropertyName] = C{:}

This expression results in an indexing structure with the dot type ('.') indexing The cell array C on the right side of the assignment statement produces a comma-separated list. This code assigns one list item to each property in the object array.

case '.'
   if length(s)==1
      prop = s(1).subs;      % Property name
      n = numel(obj);        % Number of elements in array
      for k = 1:n
         obj(k).(prop) = varargin{k};
      end
   end
end

Related Topics

Was this topic helpful?