Initialization of class instance properties

9 views (last 30 days)
It seems like Matlab initializes the properties of each instance of a class to the same, single value rather than evaluating the initialization expression for each instance. Why is this? It leads to very unexpected behavior from my perspective:
This works as expected in all cases:
classdef OK < handle
properties (Access=private)
mymap
end
methods
function this = OK()
this.mymap = containers.Map();
end
function add(this, key)
this.mymap(key) = true;
end
function keylist = keys(this)
keylist = this.mymap.keys;
end
end
end
The following class has crazy behavior in 2012b:
classdef WTF < handle
properties (Access=private)
mymap = containers.Map();
end
methods
function add(this, key)
this.mymap(key) = true;
end
function keylist = keys(this)
keylist = this.mymap.keys;
end
end
end
Try these commands:
x = WTF;
y = WTF;
x.keys
>> Empty cell array: 1-by-0
y.keys
>> Empty cell array: 1-by-0
x.add('foobar');
y.keys
>> 'asdf'
Huh? How did y magically get access to x's mymap? Basically, why does Matlab evaluate its property initialization expressions only once ever rather than once per instance?

Accepted Answer

Matt J
Matt J on 15 Jun 2013
Edited: Matt J on 15 Jun 2013
Basically, why does Matlab evaluate its property initialization expressions only once ever rather than once per instance?
The initializations in a properties block are meant for setting the DEFAULT values of the properties, i.e., the values the properties will fall back to if not initialized in the constructor. As such, these initial values are a characteristic of the class, not its instances, and are only to be computed once.
The reason you see the (interesting!!) sharing behavior between x and y is that containers.Map() produces a handle object. As the default initial value for mymap, that map object gets copied around from instance to instance, but with handle semantics (i.e., by reference). So, every instance shares a copy of the map.
If instead you were to initialize mymap with a value object, then different class instances could make unshared changes to their own copies of mymap.
  2 Comments
Ben
Ben on 17 Jun 2013
Yeah, it does seem like that's what Matlab is doing. That still seems like very non-standard OOP behavior; as far as I know, every other language I've used performs the initialization once per instance rather than once per class. I'd be interested to know why Mathworks chose this approach and/or whether it was intentional (perhaps they just didn't notice when they introduced handle classes).
Matt J
Matt J on 17 Jun 2013
I'd be interested to know if was intended behavior as well. However, I don't know that it's behavior I would necessarily get rid of. I can imagine various ways to exploit it.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!