Jim
Jim

Reputation: 142

When constructing an array of default objects in MATLAB, why is the first element not constructed as instructed?

That's a terrible title, but let me try to explain. I have a class test_class that may be constructed one of two ways. I can create a single object with default properties by calling test_obj = test_class, or I can create an array of objects with default properties by calling test_obj_array = test_class([x,y]). Here's the full code:

classdef test_class

    properties
        A;
    end

    properties (Dependent = true)
        B;
    end

    methods

        function obj = test_class(S)

            if nargin == 0
                obj.A = 1;
            else
                x = size(S,1);
                y = size(S,2);
                obj(x,y) = test_class;
            end

        function B_value = get.B(obj)

            B_value = obj.A * 2;

        end

    end

end

Now, when I check the properties of these objects:

test_obj_array(1,1).A = []
test_obj_array(1,1).B = []

test_obj_array(1,2).A = 1
test_obj_array(1,2).B = 2
...

Why is the first object in the array not constructed?

Now, it's easy to fix by adding test_obj_array(1,1) = test_class or by modifying the properties later, but that's an easy thing to forget and a difficult thing to troubleshoot.

Note: this behavior is not seen if you pass an array of values to the constructor, as demonstrated in this MATLAB documentation.

Upvotes: 2

Views: 77

Answers (1)

tmpearce
tmpearce

Reputation: 12693

I'm not entirely sure what's going on under the hood here to make this behavior happen. However, from the MATLAB documentation on initializing object arrays, the syntax you can use to get the behavior you want is:

test_obj_array(x,y) = test_class;

This will call the default constructor properly.

Based on the documentation, which says

When MATLAB calls a constructor with no arguments to initialize an object array, one of the following assignments occurs:

  • If property definitions specify default values, MATLAB assigns these values.
  • If the constructor assigns values in the absence of input arguments, MATLAB assigns these values.
  • If neither of the preceding situations apply, MATLAB assigns the value of empty double (that is, []) to the property.

In your case, the second bullet point ought to apply, but isn't for some reason. I set some breakpoints inside the constructor, and when the object is initialized as an array from outside (i.e. the syntax I suggest above, that works), the default ctor is called for each non-explicitly-constructed object. When initializing the array from inside the ctor, though, the default ctor isn't being called. This is perhaps due to the expectation that each object will need to be explicitly initialized anyway (how array syntax is expected to work in the examples in the docs), so why do it twice, but... I agree with you, and I consider this a bug or at least a poor design choice by Mathworks.


On a side note, the logic you're using (that isn't working anyway) to determine the size of the array is messed up. Passing [3, 5] gives you a 1x2 array as a result, because size(S) is 1x2, not 3x5...

Upvotes: 1

Related Questions