"Steven Lord" <Steven_Lord@mathworks.com> wrote in message <m42fuq$ncg$1@newscl01ah.mathworks.com>...
>
> "Richard Pitre" <richard.pitre@robtre.com> wrote in message
> news:m40l3i$9sp$1@newscl01ah.mathworks.com...
> > It can be useful for a subclass to restrict the range of values of a
> > superclass property to a subset of possibilities allowed by the
> > superclass. Overloading the set. method to accomplish this would be useful
> > for a number of reasons. Furthermore, this restriction of the language
> > provides no guarantee that the superclass invariants will be preserved by
> > the subclass. It only slightly limits the notation that the programmer can
> > use to violate those invariants. A class tree designer who doesn't
> > understand this is going to generate a train wreck in any case.
>
> A superclass author who wants to allow subclass authors to do so could call
> a method inside their property set method to perform further validation
> (above and beyond that performed by the superclass) and allow (or even
> require, by making it abstract) subclass authors to define that method
> rather than the property set method. This way valid values for the subclass
> properties would have to pass both the superclass validation and then the
> subclass validation. It's a _little_ bit trickier than that, due to the
> restrictions on a property set method, but try these lines of code using the
> sample class definitions after my signature:
>
> b1 = ball(-1) % throws the error "Balls must have a positive radius." from
> ball.m
> b2 = ball(2) % succeeds in creating a ball
> b3 = bigball(-1) % throws the error "Balls must have a positive radius."
> from ball.m
> b4 = bigball(2) % throws the error "A bigball must have a radius >= 5." from
> bigball.m
> b5 = bigball(5) % succeeds in creating a bigball
>
> If you're concerned about the fact that furtherRadiusValidation is exposed
> by the error in case b4, you can change the method in bigball.m to create an
> MException instead of calling ERROR and use the MException throwAsCaller
> method to cause the error to appear to come from ball/set.radius.
>
> throwAsCaller(MException('bigball:notBigEnough', ...
> 'A bigball must have a radius >= 5.'));
>
> > Training videos and edit-time warnings would be a better option as long as
> > the warnings can be turned off.
>
> Warnings that CAN be turned off WILL be turned off and people will forget
> about them until they get bitten by the problem about which the warning
> warned. I've seen this happen in situations where we warned, literally, for
> years about a planned change and still surprised people when we made that
> change.
>
> > For example, I don't see how to turn off the warnings I get about the
> > possibility that the final state of an object might be dependent on the
> > sequence in which the properties are set. Since you must not disallow
> > many-to-many relationships between properties of classes there will be
> > classes for which the property setting sequence matters so leave the
> > programmer alone about it and stop coloring up his code if he already
> > knows this.
>
> Which warning is this? I've probably seen it but I want to be sure of the
> specific message. Was this a runtime warning (as issued by the WARNING
> function) or an orange Code Analyzer message in the MATLAB Editor?
>
> If it's a runtime warning that has a warning identifier, you can turn that
> warning off. If it's a Code Analyzer message, you can disable it on a per
> line, per file, or permanent basis. Whether that's a good idea or not -- see
> above.
>
> *snip*
>
> --
> Steve Lord
> slord@mathworks.com
> To contact Technical Support use the Contact Us link on
> http://www.mathworks.com
>
> % begin ball.m
> classdef ball
> properties
> radius;
> end
>
> methods
> function obj = ball(r)
> obj.radius = r;
> end
>
> function obj = set.radius(obj, r)
> if ~(r > 0) % Do it this way to handle NaN correctly
> error('Balls must have a positive radius.');
> end
> furtherRadiusValidation(obj, r);
> obj.radius = r;
> end
> end
>
> methods(Hidden)
> function furtherRadiusValidation(~, ~)
> % Subclasses can define their own validation but cannot define
> % balls with a radius that is not greater than 0
> %
> % The ball base class doesn't need to perform any additional
> validation
> % beyond what's done in set.radius
> end
> end
> end
> % end ball.m
>
> % begin bigball.m
> classdef bigball < ball
> methods
> function obj = bigball(r)
> obj@ball(r);
> end
> end
>
> methods(Hidden)
> function furtherRadiusValidation(~, r)
> if r < 5
> error('A bigball must have a radius >= 5.');
> end
> end
> end
> end
> % end bigball.m
>
Matlab cannot enforce preservation of class invariants with the language as is so why cripple the syntax to maintain the delusion. Messing up Matlab's syntax only forces good programmers to generate less transparent / maintenance-suboptimal code.
This nanny tactic in an effort to prevent bad programmers from screwing up does more harm than good and slows the learning curve. It certainly doesn't result in a better tool for professional programmers.
>
> "Richard Pitre" <richard.pitre@robtre.com> wrote in message
> news:m40l3i$9sp$1@newscl01ah.mathworks.com...
> > It can be useful for a subclass to restrict the range of values of a
> > superclass property to a subset of possibilities allowed by the
> > superclass. Overloading the set. method to accomplish this would be useful
> > for a number of reasons. Furthermore, this restriction of the language
> > provides no guarantee that the superclass invariants will be preserved by
> > the subclass. It only slightly limits the notation that the programmer can
> > use to violate those invariants. A class tree designer who doesn't
> > understand this is going to generate a train wreck in any case.
>
> A superclass author who wants to allow subclass authors to do so could call
> a method inside their property set method to perform further validation
> (above and beyond that performed by the superclass) and allow (or even
> require, by making it abstract) subclass authors to define that method
> rather than the property set method. This way valid values for the subclass
> properties would have to pass both the superclass validation and then the
> subclass validation. It's a _little_ bit trickier than that, due to the
> restrictions on a property set method, but try these lines of code using the
> sample class definitions after my signature:
>
> b1 = ball(-1) % throws the error "Balls must have a positive radius." from
> ball.m
> b2 = ball(2) % succeeds in creating a ball
> b3 = bigball(-1) % throws the error "Balls must have a positive radius."
> from ball.m
> b4 = bigball(2) % throws the error "A bigball must have a radius >= 5." from
> bigball.m
> b5 = bigball(5) % succeeds in creating a bigball
>
> If you're concerned about the fact that furtherRadiusValidation is exposed
> by the error in case b4, you can change the method in bigball.m to create an
> MException instead of calling ERROR and use the MException throwAsCaller
> method to cause the error to appear to come from ball/set.radius.
>
> throwAsCaller(MException('bigball:notBigEnough', ...
> 'A bigball must have a radius >= 5.'));
>
> > Training videos and edit-time warnings would be a better option as long as
> > the warnings can be turned off.
>
> Warnings that CAN be turned off WILL be turned off and people will forget
> about them until they get bitten by the problem about which the warning
> warned. I've seen this happen in situations where we warned, literally, for
> years about a planned change and still surprised people when we made that
> change.
>
> > For example, I don't see how to turn off the warnings I get about the
> > possibility that the final state of an object might be dependent on the
> > sequence in which the properties are set. Since you must not disallow
> > many-to-many relationships between properties of classes there will be
> > classes for which the property setting sequence matters so leave the
> > programmer alone about it and stop coloring up his code if he already
> > knows this.
>
> Which warning is this? I've probably seen it but I want to be sure of the
> specific message. Was this a runtime warning (as issued by the WARNING
> function) or an orange Code Analyzer message in the MATLAB Editor?
>
> If it's a runtime warning that has a warning identifier, you can turn that
> warning off. If it's a Code Analyzer message, you can disable it on a per
> line, per file, or permanent basis. Whether that's a good idea or not -- see
> above.
>
> *snip*
>
> --
> Steve Lord
> slord@mathworks.com
> To contact Technical Support use the Contact Us link on
> http://www.mathworks.com
>
> % begin ball.m
> classdef ball
> properties
> radius;
> end
>
> methods
> function obj = ball(r)
> obj.radius = r;
> end
>
> function obj = set.radius(obj, r)
> if ~(r > 0) % Do it this way to handle NaN correctly
> error('Balls must have a positive radius.');
> end
> furtherRadiusValidation(obj, r);
> obj.radius = r;
> end
> end
>
> methods(Hidden)
> function furtherRadiusValidation(~, ~)
> % Subclasses can define their own validation but cannot define
> % balls with a radius that is not greater than 0
> %
> % The ball base class doesn't need to perform any additional
> validation
> % beyond what's done in set.radius
> end
> end
> end
> % end ball.m
>
> % begin bigball.m
> classdef bigball < ball
> methods
> function obj = bigball(r)
> obj@ball(r);
> end
> end
>
> methods(Hidden)
> function furtherRadiusValidation(~, r)
> if r < 5
> error('A bigball must have a radius >= 5.');
> end
> end
> end
> end
> % end bigball.m
>
Matlab cannot enforce preservation of class invariants with the language as is so why cripple the syntax to maintain the delusion. Messing up Matlab's syntax only forces good programmers to generate less transparent / maintenance-suboptimal code.
This nanny tactic in an effort to prevent bad programmers from screwing up does more harm than good and slows the learning curve. It certainly doesn't result in a better tool for professional programmers.