Next: Indexed Assignment Optimization, Up: Indexing Objects [Contents][Index]
Objects can be indexed with parentheses or braces, either like
obj(idx) or like obj{idx}, or even
like obj(idx).field. However, it is up to the
programmer to decide what this indexing actually means. In the case of the
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 on val according to the subscript specified by idx.
The subscript idx must 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, this class uses the convention that indexing with "()"
evaluates the polynomial and indexing with "{}" returns the
n-th coefficient (of the n-th power). The code for the
subsref method looks like
function r = subsref (p, s)
if (isempty (s))
error ("@polynomial/subsref: missing index");
endif
switch (s(1).type)
case "()"
idx = s(1).subs;
if (numel (idx) != 1)
error ("@polynomial/subsref: need exactly one index");
endif
r = polyval (fliplr (p.poly), idx{1});
case "{}"
idx = s(1).subs;
if (numel (idx) != 1)
error ("@polynomial/subsref: need exactly one index");
endif
if (isnumeric (idx{1}))
r = p.poly(idx{1}+1);
else
r = p.poly(idx{1});
endif
case "."
fld = s.subs;
if (! strcmp (fld, "poly"))
error ('@polynomial/subsref: invalid property "%s"', fld);
endif
r = p.poly;
otherwise
error ("@polynomial/subsref: invalid subscript type");
endswitch
if (numel (s) > 1)
r = subsref (r, 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 must 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.
See also: subsref, substruct, optimize_subsasgn_calls.
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.
See also: subsasgn.
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 there must be an end method defined. For example, the
end method for the 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. An example using the polynomial
class is then
p = polynomial ([1,2,3,4]);
p{end-1}
⇒ 3
Objects can also be used themselves as the index in a subscripted expression
and this is controlled by the subsindex function.
Convert an object to an index vector.
When obj 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 were
function obj = myclass (a)
obj = class (struct ("a", a), "myclass");
endfunction
then the subsindex function
function idx = subsindex (obj) idx = double (obj.a) - 1.0; endfunction
could be used as follows
a = myclass (1:4); b = 1:10; b(a) ⇒ 1 2 3 4
Finally, objects can be used like ranges by providing a colon method.
Next: Indexed Assignment Optimization, Up: Indexing Objects [Contents][Index]