When would dotListLength as part of matlab.mix​in.indexin​g.Redefine​sDot return something other than 1?

49 views (last 30 days)
My understanding is that dotListLength should return the number of output arguments of whatever you are overloading dotAssign and dotReference.
It also seems like dotListLength does not get called when a method of that class is called.
See my example below:
classdef ScalarStructClass2 < matlab.mixin.indexing.RedefinesDot & ...
matlab.mixin.Scalar
properties (Dependent, SetAccess=private)
FieldNames
end
properties (Access=private)
AddedFields struct
end
methods
function out = get.FieldNames(obj)
out = string(fieldnames(obj.AddedFields));
end
end
methods (Access=public)
function obj = ScalarStructClass2(fieldName,fieldValue)
if nargin == 1
obj.AddedFields = fieldName;
return;
end
obj.AddedFields = struct(fieldName,fieldValue);
end
function out = getAddedFields(obj)
out = obj.AddedFields;
end
function [a, b] = getSomething(obj)
a=1;
b=2;
end
end
methods (Access=protected)
function varargout = dotReference(obj,indexOp)
[varargout{1:nargout}] = obj.AddedFields.(indexOp);
end
function obj = dotAssign(obj,indexOp,varargin)
[obj.AddedFields.(indexOp)] = varargin{:};
end
function n = dotListLength(obj,indexOp,indexContext)
n = listLength(obj.AddedFields,indexOp,indexContext);
fprintf(1, "Num Fields: %i\n", n);
end
end
end
I tried the following:
myStructClass = ScalarStructClass2("Field1",75)
myStructClass.Field1 % dotListLength returns 1
myStructClass.getSomething() % dotListLength is not called
myStructClass.testField = randn(6,6); % dotListLength is not called
myStructClass.testField % dotListLength returns 1
myStructClass.testField(2:4,3:5) % dotListLength is not called but dotReference is (WHY?)
myStructClass.testField(2:4,3:5) = ones(3,3) % dotListLength is not called
myStructClass.test = {1, 2, 3, 4} % dotListLength is not called
[aaa, bbb] = myStructClass.test{1:2} % dotListLength and dotAssign is not called, but dotReference is
tt = struct;
tt.bb.cc.dd = 5;
myStructClass.tt = tt % dotListLength is not called
myStructClass.tt.bb.cc % dotListLength returns 1
myStructClass.tt.bb.cc.ee = 3;
myStructClass.tt.bb.cc % dotListLength returns 1
Can someone help me understand what exactly is dotListLength doing and why would it not just return 1?
Also, in my test above with: myStructClass.testField(2:4,3:5) - why is dotListLength not even called?

Answers (1)

Gayatri
Gayatri on 4 Apr 2024 at 6:20
Edited: Gayatri on 4 Apr 2024 at 6:26
Hi Cole,
  • "dotListLength" is specifically for handling index operations and determining the length of these operations. It's not always called because MATLAB doesn't always need this information, especially in cases where direct property access or simple indexing is performed.
  • In your test cases, you have observed that "dotListLength" is not always called and sometimes "dotReference" is called without "dotListLength".
  • "dotListLength" is only called when MATLAB encounters index operations. When you directly call a method (e.g., getSomething()), you are not engaging in a dot indexing operation. Instead, you are invoking a method with a fixed signature, where the number of outputs is determined by the method definition itself, not by indexing semantics.
  • When you access a field directly (e.g., myStructClass.Field1), MATLAB doesn't perform an indexing operation. it directly accesses the property value, so "dotListLength" is not called.
  • When performing an assignment to an indexed expression (e.g., myStructClass.testField(2:4,3:5) = ones(3,3)), the focus is on modifying the object's state, not on retrieving variable outputs, so "dotListLength" might not be invoked.
  • For operations like indexing into a property with a complex expression (e.g., myStructClass.testField(2:4,3:5)), if MATLAB can resolve the operation without needing to dynamically determine the number of outputs (e.g., when the operation clearly maps to a single output or when the operation modifies the object's state), it might not invoke "dotListLength".
I hope it helps!
  3 Comments
Kyle
Kyle on 16 Apr 2024 at 17:51
Hi Cole,
One example of dotListLength returning something other than 1 is in a case where you chain multiple expressions together. For example, imagine if your testField was an array of objects, rather than an array of doubles:
myStructClass.testField(2,2).myMethod()
In this example, myMethod() is allowed to have any number of output arguments. Even though myStructClass.testField(2,2) may only return one output, dotListLength must be accurate for the entire dot expression, including the full indexContext. ScalarStructClass2 does not have enough information to determine the number of outputs on its own. This is why the implementation of your dotListLength returns n = listLength(obj.AddedFields,indexOp,indexContext);. It must "look ahead" and see how many outputs there are when the later indexOps are applied to obj.AddedFields. If the myMethod() definition has two outputs (like your getSomething method does), dotListLength would return 2 instead.
Cole
Cole on 16 Apr 2024 at 20:09
Got it - the example would be if there's a chain the expression and the final piece of the chain is a method that has multiple outputs.

Sign in to comment.

Categories

Find more on Customize Object Indexing in Help Center and File Exchange

Products


Release

R2024a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!