Next: Indexed Assignment Optimization, Up: Indexing Objects [Contents][Index]
Objects can be indexed with parentheses, 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.
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 first two 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)
.
If idx is an empty structure array with fields ‘type’ and ‘subs’, return val.
For example we might decide that indexing with "()"
evaluates the
polynomial and indexing with "{}"
returns the n-th coefficient
(of n-th power). In this case the subsref
method of our
polynomial class might look like
function b = subsref (a, s) if (isempty (s)) error ("polynomial: missing index"); endif switch (s(1).type) case "()" ind = s(1).subs; if (numel (ind) != 1) error ("polynomial: need exactly one index"); else b = polyval (fliplr (a.poly), ind{1}); endif case "{}" ind = s(1).subs; if (numel (ind) != 1) error ("polynomial: need exactly one index"); else if (isnumeric (ind{1})) b = a.poly(ind{1}+1); else b = a.poly(ind{1}); endif endif case "." fld = s.subs; if (strcmp (fld, "poly")) b = a.poly; else error ("@polynomial/subsref: invalid property \"%s\"", fld); endif otherwise error ("invalid subscript type"); endswitch if (numel (s) > 1) b = subsref (b, s(2:end)); endif endfunction
The equivalent functionality for subscripted assignments uses the
subsasgn
method.
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
.
If idx is an empty structure array with fields ‘type’ and ‘subs’, return rhs.
Query or set the internal flag for subsasgn method call optimizations.
If true, Octave will attempt to eliminate the redundant copying when calling the subsasgn method of a user-defined class.
When called from inside a function with the "local"
option, the
variable is changed locally for the function and any subroutines it calls.
The original variable value is restored when exiting the function.
Note that the subsref
and subsasgn
methods always receive the
whole index chain, while they usually handle only the first element. It is the
responsibility of these methods to handle the rest of the chain (if needed),
usually by forwarding it again to subsref
or subsasgn
.
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) if (num_indices != 1) error ("polynomial object may only have one index") endif r = length (obj.poly) - 1; 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 as
follows:
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.
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 = class (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
Finally, objects can equally be used like ranges, using the colon
method
Return the result of the colon expression corresponding to base, limit, and optionally, increment.
This function is equivalent to the operator syntax base : limit
or base : increment : limit
.
Next: Indexed Assignment Optimization, Up: Indexing Objects [Contents][Index]