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

21 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)

Categories

Find more on Data Type Identification in Help Center and File Exchange

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!