Last week, I presented the list of undocumented properties available in Matlab’s cursor mode and data-tip objects. Over the past two years, I had posted quite a few other articles on this website that used such undocumented properties. So today I will show exactly how such properties can be discovered.
Hidden properties are object properties that for some reason or other MathWorks has decided not to expose to the general public. They can still be used by Matlab users, just like any other regular property. But if you use the built-in get and set functions to list the object’s properties, you will not find the hidden properties listed. You need to know the hidden properties’ exact name in order to use them. Which is where today’s post can help, by showing you how to list these hidden properties. I wrote about this a couple of years ago, and today’s article will expand on that original post.
Hidden properties are by their very nature undocumented and not officially supported. For this reason, you should take extra care when relying on them in your code. They could change functionality or even be removed without prior notice in any future Matlab release. Still, some of these properties enable very important functionality, as I have often shown on this website.
HideUndocumented
There are two distinct manners by which undocumented properties can be seen in Matlab. The simplest was reported by Hans Olsson all the way back in 1997, in one of the very earliest posts on the CSSM newsgroup (there is no earlier public report, as far as I could tell). Since then, this method was mentioned in about a dozen other CSSM posts.
By setting the Matlab root (handle 0)’s HideUndocumented property to ‘off’ (default=’on’), subsequent calls to the built-in get and set functions list the hidden properties in addition to the regular ones. Note that HideUndocumented is itself a hidden property, which is why Hans’ post is so important – he presented us with the loose end that then enabled us to untangle the hidden properties in any other HG object.
Here is a simple example, showing HideUndocumented‘s effect on the root (handle 0) object handle itself (hidden properties are highlighted):
% Display only regular properties >> get(0) CallbackObject = [] CommandWindowSize = [86 51] CurrentFigure = [] Diary = off DiaryFile = diary Echo = off FixedWidthFontName = Courier New Format = longG FormatSpacing = compact Language = he_il MonitorPositions = [ (2 by 4) double array] More = off PointerLocation = [1084 590] RecursionLimit = [500] ScreenDepth = [32] ScreenPixelsPerInch = [96] ScreenSize = [1 1 1440 900] ShowHiddenHandles = off Units = pixels BeingDeleted = off ButtonDownFcn = Children = [] Clipping = on CreateFcn = DeleteFcn = BusyAction = queue HandleVisibility = on HitTest = on Interruptible = on Parent = [] Selected = off SelectionHighlight = on Tag = Type = root UIContextMenu = [] UserData = [] Visible = on % Display ALL properties (including hidden ones, which are highlighted below) >> set(0,'HideUndocumented','off') >> get(0) BlackAndWhite = off CallbackObject = [] CommandWindowSize = [86 51] CurrentFigure = [] Diary = off DiaryFile = diary Echo = off ErrorMessage = [ (1 by 79) char array] FixedWidthFontName = Courier New Format = longG FormatSpacing = compact HideUndocumented = off Language = he_il MonitorPositions = [ (2 by 4) double array] More = off PointerLocation = [1022 82] PointerWindow = [0] RecursionLimit = [500] ScreenDepth = [32] ScreenPixelsPerInch = [96] ScreenSize = [1 1 1440 900] ShowHiddenHandles = off Units = pixels AutomaticFileUpdates = on BeingDeleted = off PixelBounds = [0 0 0 0] ButtonDownFcn = Children = [] Clipping = on CreateFcn = DeleteFcn = BusyAction = queue HandleVisibility = on HelpTopicKey = HitTest = on Interruptible = on Parent = [] Selected = off SelectionHighlight = on Serializable = on Tag = Type = root UIContextMenu = [] UserData = [] ApplicationData = [ (1 by 1) struct array] Behavior = [ (1 by 1) struct array] Visible = on XLimInclude = on YLimInclude = on ZLimInclude = on CLimInclude = on ALimInclude = on IncludeRenderer = on
Property definitions
An entirely different mechanism uses the schema.prop definitions that were presented here by Donn Scull at the beginning of 2011. The idea is to get the object’s classhandle reference, from it to get the list of properties definitions, and for each property look at its Visible meta-property: hidden properties will simply have Visible=’off’, whereas regular properties will have ‘on’.
It turns out that there is not always a full correspondence between these two mechanism. I can’t remember specific examples, and perhaps these were fixed in the latest Matlab releases. It doesn’t matter, because merging the list of hidden properties reported by these two methods is always safe to do. Which is exactly what my getundoc utility does:
getundoc utility
The getundoc utility is based on another utility by the same name, posted by Duane Hanselman to the Matlab File Exchange in 2006 (Duane has elected to remove all his submissions from FEX a year or two ago, but that’s an entirely separate [and extremely heated] topic for a different discussion). Duane’s original getundoc utility relied only on the first (HideUndocumented) mechanism.
I have since expanded this utility to include support for the second mechanism, as well as support for the upcoming HG2 (see below). The updated getundoc is now available for download on the File Exchange. Since it’s a very short utility, I will digress from my norm and simply present its code, in its present form, here:
function c = getundoc(arg) %GETUNDOC Get Undocumented Object Properties. % GETUNDOC('OBJECT') or GETUNDOC(H) returns a structure of % undocumented properties (names & values) for the object having handle % H or indentified by the string 'OBJECT'. % % For example, GETUNDOC('axes') or GETUNDOC(gca) returns undocumented % property names and values for the axes object. % Extension of Duane Hanselman's original utility (which is no longer % available on the File Exchange): % D.C. Hanselman, University of Maine, Orono, ME 04469 % MasteringMatlab@yahoo.com % Mastering MATLAB 7 % 2006-01-06 if nargin~=1 error('One Input Required.') end if ischar(arg) % GETUNDOC('OBJECT') switch lower(arg) case 'root' % root h=0; hf=0; case 'figure' % figure h=figure('Visible','off'); hf=h; otherwise % some other string name of an object hf=figure('Visible','off'); object=str2func(arg); try h=object('Parent',hf,'Visible','off'); catch error('Unknown Object Type String Provided.') end end elseif ishandle(arg) % GETUNDOC(H) h=arg; hf=0; else error('Unknown Object Handle Provided.') end wstate=warning; warning off % supress warnings about obsolete properties try set(0,'HideUndocumented','off'); catch; end % Fails in HG2 undocfnames=fieldnames(get(h)); % get props including undocumented try set(0,'HideUndocumented','on'); catch; end % Fails in HG2 docfnames=fieldnames(get(h)); % get props excluding undocumented % Yair 18/3/2010 - add a few more undocs: try % This works in HG1 props = get(classhandle(handle(h)),'properties'); undocfnames = [undocfnames; get(props(strcmp(get(props,'Visible'),'off')),'Name')]; catch % Yair 18/9/2011: In HG2, the above fails, so use the following workaround: try prop = findprop(handle(h),undocfnames{1}); props = prop.DefiningClass.PropertyList; undocfnames = [undocfnames; {props.Name}']; % {props([props.Hidden]).Name} catch % ignore... end end c = setdiff(undocfnames,docfnames); % extract undocumented % Get the values in struct format, if relevant if ~isempty(c) s = struct; for fieldIdx = 1 : length(c) try fieldName = c{fieldIdx}; s.(fieldName) = get(h,fieldName); catch s.(fieldName) = '???'; end end c = s; end % Yair end if hf~=0 % delete hidden figure holding selected object delete(hf) end warning(wstate)
Usage of this utility is extremely simple:
>> getundoc(0) ans = ALimInclude: 'on' ApplicationData: [1x1 struct] AutomaticFileUpdates: 'on' Behavior: [1x1 struct] BlackAndWhite: 'off' CLimInclude: 'on' ErrorMessage: [1x79 char] HelpTopicKey: '' HideUndocumented: 'on' IncludeRenderer: 'on' PixelBounds: [0 0 0 0] PointerWindow: 0 Serializable: 'on' XLimInclude: 'on' YLimInclude: 'on' ZLimInclude: 'on' >> getundoc(gcf) ans = ALimInclude: 'on' ActivePositionProperty: 'position' ApplicationData: [1x1 struct] BackingStore: 'on' Behavior: [1x1 struct] CLimInclude: 'on' CurrentKey: '' CurrentModifier: {1x0 cell} Dithermap: [64x3 double] DithermapMode: 'manual' DoubleBuffer: 'on' ExportTemplate: [] FixedColors: [3x3 double] HelpFcn: '' HelpTopicKey: '' HelpTopicMap: '' IncludeRenderer: 'on' JavaFrame: [1x1 com.mathworks.hg.peer.HG1FigurePeer] MinColormap: 64 OuterPosition: [436 374 568 502] PixelBounds: [0 0 560 420] PrintTemplate: [] Serializable: 'on' UseHG2: 'off' WaitStatus: [] XLimInclude: 'on' YLimInclude: 'on' ZLimInclude: 'on'
Fixes for HG2
Unfortunately, in the new HG2 (which is still not in production, but we must be prepared, mustn’t we?), the original mechanism above (HideUndocumented) fails completely (there is no such property in the new matlab.ui.root
object), whereas the second mechanism (UDD property defs) needs to be modified: Apparently, classhandle fails for HG2 object handles. Instead, we use the workaround of using findprop to get the property definition for any regular property, then get its parent (the requested class definition), and then down again to list all available properties. Note that in HG2, the relevant meta-property is Hidden which holds logical (true/false) values, as opposed to Visible and ‘off’/'on’ values for HG1 above.
All of these fixes are now incorporated in the getundoc code that is listed above.
When comparing the list of hidden properties in the existing HG1 and the new HG2, we see many interesting differences. And yes: the figure’s JavaFrame property was indeed removed in HG2. Bummer! (don’t worry – there are several workarounds up my sleeve…)
Do you have any favorite hidden property that you use in your code? If so, please tell us about it in a comment below.
p.s. – For all the numerous good people telling me about cprintf – Yes: I am aware that the latest R2011b release has broken cprintf‘s functionality. I plan to release a workaround sometime soon, when I have some spare time. I’ll keep everybody posted of course. Please be patient. (if you can’t wait, you can always hire me to fix it sooner; otherwise I need to give priority to my paying clients…)
Related posts:
- Undocumented cursorbar object Matlab's internal undocumented graphics.cursorbar object can be used to present dynamic data-tip cross-hairs...
- Accessing private object properties Private properties of Matlab class objects can be accessed (read and write) using some undocumented techniques. ...
- UDD Properties UDD provides a very convenient way to add customizable properties to existing Matlab object handles...
- Plot LimInclude properties The plot objects' XLimInclude, YLimInclude, ZLimInclude, ALimInclude and CLimInclude properties are an important feature, that has both functional and performance implications....