Next: Overloading Objects, Previous: Manipulating Classes, Up: Object Oriented Programming

### 33.3 Indexing Objects

Objects in can be indexed with parenthesises, either like a`(`idx`)` or like a`{`idx`}`, or even like a`(`idx`).`field. However, it is up to the user to decide what this indexing actually means. In the case of our polynomial class p`(`n`)` might mean either the coefficient of the n-th power of the polynomial, or it might be the evaluation of the polynomial at n. The meaning of this subscripted referencing is determined by the `subsref` method.

— Built-in Function: subsref (val, idx)

> Perform the subscripted element selection operation according to the subscript specified by idx.

> The subscript idx is expected to be a structure array with fields ‘`type`’ and ‘`subs`’. Valid values for ‘`type`’ are ‘`"()"`’, ‘`"{}"`’, and ‘`"."`’. The ‘`subs`’ field may be either ‘`":"`’ or a cell array of index values.

> The following example shows how to extract the two first columns of a matrix

>               val = magic(3)
>                     val = [ 8   1   6
>                               3   5   7
>                               4   9   2 ]
>               idx.type = "()";
>               idx.subs = {":", 1:2};
>               subsref(val, idx)
>                     [ 8   1
>                         3   5
>                         4   9 ]

> Note that this is the same as writing `val(:,1:2)`.

> See also: subsasgn, substruct.

For example we might decide that indexing with "()" evaluates the polynomial and indexing with "{}" returns the n-th coefficient. In this case the `subsref` method of our polynomial class might look like

         function b = subsref (a, s)
           switch s.type
             case "()"
               ind = s.subs;
               b = polyval (fliplr(a.poly), ind{:});
             case "{}"
               ind = s.subs;
               b = polynomial (a.poly(ind{:}));
             case "."
               fld = s.subs;
               if (strcmp (fld, "poly"))
         	b = a.poly;
               else
         	error ("@polynomial/subsref: invalid property \"%s\"",
         	       fld);
               endif
           endswitch
         endfunction

The equivalent functionality for subscripted asignments uses the `subsasgn` method.

— Built-in Function: subsasgn (val, idx, rhs)

> Perform the subscripted assignment operation according to the subscript specified by idx.

> The subscript idx is expected to be a structure array with fields ‘`type`’ and ‘`subs`’. Valid values for ‘`type`’ are ‘`"()"`’, ‘`"{}"`’, and ‘`"."`’. The ‘`subs`’ field may be either ‘`":"`’ or a cell array of index values.

> The following example shows how to set the two first columns of a 3-by-3 matrix to zero.

>               val = magic(3);
>               idx.type = "()";
>               idx.subs = {":", 1:2};
>               subsasgn (val, idx, 0)
>                     [ 0   0   6
>                         0   0   7
>                         0   0   2 ]

> Note that this is the same as writing `val(:,1:2) = 0`.

> See also: subsref, substruct.

If you wish to use the `end` keyword in subscripted expressions of an object. Then the user needs to define the `end` method for the class.

For example the `end` method for our polynomial class might look like

         function r = end (obj, index_pos, num_indices)
           dv = size (obj.x);
           for i = (num_indices + 1) : length (dv)
             dv(num_indices) *= dv(i);
           endfor
           if (index_pos <= length (dv))
             r = dv (index_pos);
           elseif
             r = 1;
           endif
         endfunction

which is a fairly generic `end` method that has a behavior similar to the `end` keyword for Octave Array classes. It can then be used for example like

         p = polynomial([1,2,3,4]);
         p(end-1)
          3

Objects can also be used as the index in a subscripted expression themselves and this is controlled with the `subsindex` function.

— Function File: idx = subsindex (a)

> Convert an object to an index vector. When a is a class object defined with a class constructor, then `subsindex` is the overloading method that allows the conversion of this class object to a valid indexing vector. It is important to note that `subsindex` must return a zero-based real integer vector of the class "double". For example, if the class constructor

>               function b = myclass (a)
>                b = myclass (struct ("a", a), "myclass");
>               endfunction

> then the `subsindex` function

>               function idx = subsindex (a)
>                idx = double (a.a) - 1.0;
>               endfunction

> can then be used as follows

>               a = myclass (1:4);
>               b = 1:10;
>               b(a)
>                1  2  3  4

> See also: class, subsref, subsasgn.

Finally, objects can equally be used like ranges, using the `colon` method

— Function File: r = colon (a, b)
— Function File: r = colon (a, b, c)

> Method of a class to construct a range with the `:` operator. For example.

>               a = myclass (...)
>               b = myclass (...)
>               c = a : b

> See also: class, subsref, subsasgn.