Addressing error message: Invalid default value for property in class: Constant property in class cannot be used in its own definition.

9 views (last 30 days)
Hello,
I am encountering this error:
Error using Hex
Invalid default value for property 'directions' in class 'Hex':
Constant property 'directions' in class Hex cannot be used in its own definition.
while using the class defined below. However I am having quite a bit of difficulty reliably recreating the error. It triggers when creating an instance of the class. Sometimes I can comment out some methods and the creation of an object runs smoothly, then I can re-introduce the method line by line until it is the same as before being commented and there will still be no error.
I know that the problem is a bit vague here if anyone could shed some light on what might be causing this error it would be greatly appreciated.
Currently, if I comment out the line which defines 'diagonals' then I can call a class like so:
>> Hex(2,2,-4)
ans =
Hex with properties:
q: 2
r: 2
s: -4
address: '2.2.-4'
directions: {6×1 cell}
If the line
diagonals = {Hex(2,-1,-1);Hex(1,-2,1);Hex(-1,-1,2);Hex(-2,1,1);Hex(-1,2,-1);Hex(1,1,-2)};
remains uncommented, then I get the error:
>> Hex(2,2,-4)
Error using Hex
Invalid default value for property 'directions' in class 'Hex':
Constant property 'directions' in class Hex cannot be used in its own definition.
I am able to access the 'directions' property when a class is made:
>> Hex(2,2,-4).directions{1}
ans =
Hex with properties:
q: 1
r: 0
s: -1
address: '1.0.-1'
directions: {6×1 cell}
So I figured that the line for 'diagonals' should be the same. I am a bit nonplussed.
Here is my class:
classdef Hex
properties (SetAccess = immutable)
q
r
s
address
end
properties (Constant)
directions = {Hex(1,0,-1);Hex(1,-1,0);Hex(0,-1,1);Hex(-1,0,1);Hex(-1,1,0);Hex(0,1,-1)};
diagonals = {Hex(2,-1,-1);Hex(1,-2,1);Hex(-1,-1,2);Hex(-2,1,1);Hex(-1,2,-1);Hex(1,1,-2)};
end
methods
function obj = Hex(q,r,s)
assert(q + r + s == 0,"Invalid hex coordinates.");
obj.q = q;
obj.r = r;
obj.s = s;
obj.address = char(string(obj.q)+"."+string(obj.r)+"."+string(obj.s));
end
function e = eq(obj1,obj2)
if(length(obj1) > 1 || length(obj2) > 1)
msg = "Cannot currently compare two lists of hexes.";
assert((length(obj1) == 1 || length(obj2) == 1),msg);
if(length(obj1) > 1)
temp = obj2;
obj2 = obj1;
obj1 = temp;
end
for i = 1:length(obj2)
if(obj1 == obj2(i))
e(i) = true;
else
e(i) = false;
end
end
else
if(obj1.q == obj2.q && obj1.r == obj2.r && obj1.s == obj2.s)
e = true;
else
e = false;
end
end
end
function e = ne(obj1,obj2)
if(obj1.q == obj2.q && obj1.r == obj2.r && obj1.s == obj2.s)
e = true;
else
e = false;
end
end
function hex = hex_add(A,B)
hex = Hex(A.q+B.q,A.r+B.r,A.s+B.s);
end
function hex = hex_subtract(A,B)
hex = Hex(A.q-B.q,A.r-B.r,A.s-B.s);
end
function hex = hex_multiply(A,k)
hex = Hex(A.q*k,A.r*k,A.s*k);
end
function ln = hex_length(A)
ln = max([abs(A.q),abs(A.r),abs(A.s)]);
end
function d = hex_distance(A,B)
d = hex_length(hex_subtract(A,B));
end
function neighbour = hex_neighbour(hex,direction)
neighbour = hex_add(hex,hex.hex_direction(direction));
end
function neighbour = hex_diagonal_neighbour(hex,direction)
neighbour = hex_add(hex,Hex.diagonals{direction});
end
function point = to_pixel(hex,layout)
M = layout.orientation;
x = (M.f1 * hex.q + M.f2 * hex.r) * layout.size.x;
y = (M.f3 * hex.q + M.f4 * hex.r) * layout.size.y;
point = Point(x + layout.origin.x,y + layout.origin.y);
end
function corners = polygon_corners(hex, layout)
center = hex.to_pixel(layout);
corners(1:6) = Point(0,0);
for i = 0:6
offset = Hex.corner_offset(layout,i);
corners(i+1) = (Point(center.x + offset.x, center.y + offset.y));
end
end
function fracHex = hex_linearly_interpolate(A, B, t)
fracHex = FractionalHex(Hex.linearly_interpolate(A.q,B.q,t),Hex.linearly_interpolate(A.r,B.r,t),Hex.linearly_interpolate(A.s,B.s,t));
end
function hexList = linedraw(A,B)
N = A.hex_distance(B);
hexList = Hex(0,0,0);
step = 1 / max(N,1);
for i = 0:N
hexList(i+1) = hex_round(hex_linearly_interpolate(A,B,step * i));
end
end
function offsetCoord = cube_to_oddr(hex)
col = hex.q + (hex.r -(mod(hex.r,2))) / 2;
row = hex.r;
offsetCoord = [col,row];
end
function hex = hex_scale(hex,factor)
hex = Hex(hex.q * factor, hex.r * factor, hex.s * factor);
end
end
methods (Static)
function direction = hex_direction(dir)
dir = mod(dir,6) + 1;
direction = Hex.directions{dir};
end
function fracHex = pixel_to_hex(layout, point)
M = layout.orientation;
pt = Point((point.x - layout.origin.x) / layout.size.x, (point.y - layout.origin.y) / layout.size.y);
q = M.b1 * pt.x + M.b2 * pt.y;
r = M.b3 * pt.x + M.b4 * pt.y;
s = 0 - q - r;
fracHex = FractionalHex(q,r,s);
end
function point = corner_offset(layout, corner)
size = layout.size;
angle = 2 * pi * (layout.orientation.startAngle + corner) / 6;
point = Point(size.x * cos(angle), size.y * sin(angle));
end
function c = linearly_interpolate(a, b, t)
c = a * (1 - t) + b * t;
end
function hex = oddr_to_cube(col,row)
q = col - (row - (mod(row,2))) / 2;
r = row;
s = 0 - q - r;
hex = Hex(q,r,s);
end
end
end

Accepted Answer

Joes Edders
Joes Edders on 2 Jun 2022
I believe that I have now found the cause of this.
I had not defined the Hex class as a handle class.
classdef Hex < handle
As per the documentation here,
"You can assign an instance of the defining class to a constant property. MATLAB creates the instance assigned to the constant property when loading the class. Use this technique only when the defining class is a handle class."

More Answers (0)

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!