bugGNU Octave - Bugs: bug #61673, classdef (Access = hidden) should...

 
 

bug #61673: classdef (Access = hidden) should have stronger syntax checking

Submitter:  Nicholas Jankowski <nrjank>
Submitted:  Tue 14 Dec 2021 08:10:54 PM UTC
 
Category:  Classdef Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  Confirmed Assigned to:  None
Originator Name:  Nicholas Jankowski Open/Closed:  * Open
Release:  * dev Operating System:  * Any
* Mandatory Fields

Add a New Comment (Rich Markup)
   

Comment Type & Canned Response:
       

 

( Jump to the original submission )

Wed 15 Dec 2021 07:32:32 PM UTC, comment #16: 

OK, so it makes sense to limit the types of expressions that may appear inside the list of attributes.

John W. Eaton <jwe>
Project Administrator
Wed 15 Dec 2021 05:28:27 PM UTC, comment #15: 

For a methods block as shown in comment #14, Matlab errors on constructing an object with:

>> t = testclassdef
Error using testclassdef
File: testclassdef.m Line: 21 Column: 17
Invalid use of operator.

It doesn't seem to matter if the methods block is empty or not. So, that error might be from the parser...

Markus Mützel <mmuetzel>
Project Member
Wed 15 Dec 2021 04:57:21 PM UTC, comment #14: 

RE: Comment #12.  Currently, Octave parses an attribute specification as one of

identifier
identfier '=' expression
EXPR_NOT identifier

Unless there is something else that should be allowed, that probably doesn't need to change, unless Matlab allows things like

methods (some + arbitrary + expression)
end

without error or warning.

Either way, validating the attribute expression can be deferred until the classdef object is finally constructed.  It doesn't need to happen when the syntax is initially parsed.

John W. Eaton <jwe>
Project Administrator
Wed 15 Dec 2021 04:48:47 PM UTC, comment #13: 

I assume the way Octave is evaluating the attributes was just done because it was easy?  Adding more restrictions on the exact form that is acceptable and not actually evaluating the expressions (so that we don't call functions with side effects, for example) is more difficult but something we clearly should be doing.  If the block is empty, then there is no need to examine the contents of the attributes list if the block is empty.  The only requirement is that the basic syntax is OK.  I see no reason for Octave to do that differently.

John W. Eaton <jwe>
Project Administrator
Wed 15 Dec 2021 04:46:52 PM UTC, comment #12: 

In addition singular meta-classes seem to work:

classdef testclassdef

  methods (Access = public)
    function this = testclassdef (varargin)
      a = 1;
    end
  end

  methods (Access = {?testclassdef2, ?testclassdef3})
    function this = say_hello(this)
      disp('hello');
    end
  end

  methods (Access = ?testclassdef2)
    function this = say_hello2(this)
      disp('hello2');
    end
  end

end

So, it looks like the following is allowed for the `Access` attribute:
- any of the keywords `public`, `private`, `protected`
- string literals corresponding to these keywords: `'public'`, `'private'`, `'protected'`
- single meta-class objects (like `?testclassdef2`)
- cell arrays of meta-class objects (like `{?testclassdef2, ?testclassdef3}`)

Everything else seems to result in an error on construction (if the methods-block is not empty).

Markus Mützel <mmuetzel>
Project Member
Wed 15 Dec 2021 04:43:04 PM UTC, comment #11: 

trying that in octave, and the say_hello function is available.

I don't seem to be able to break 'public' though by setting public = 1, public = 'private', creating a public(), etc. seems to treat it as public no matter what I do.  so it seems to parse as a keyword if it's an expected value, or look for other options if it's not (hence it parsed hidden and return_public). 

i would suggest that's functionality we don't need, unless that's some dynamic object capability i can't see a good use for.

Nicholas Jankowski <nrjank>
Project Member
Wed 15 Dec 2021 04:32:23 PM UTC, comment #10: 

just tried it.  get the :

Error using testclassdef
Error: File: testclassdef.m Line: 9 Column: 21
'Access' must be public, protected, private or a list of classes.  For more information,
see Specify Access to Class Members.

curiously, matlab doesn't error if the methods block is empty. seems to ignore the block altogether.

Nicholas Jankowski <nrjank>
Project Member
Wed 15 Dec 2021 04:31:03 PM UTC, comment #9: 

@Rik: That fails with the same error message.

A similar test did succeed though:

classdef testclassdef

  methods (Access = public)
    function this = testclassdef (varargin)
      a = 1;
    end
  end

  methods (Access = 'public')
    function this = say_hello(this)
      disp('hello');
    end
  end

end

So, literal strings corresponding to the allowed keywords are also ok. Literal strings that differ from any of the allowed keywords result in an error on object construction (if the `methods` block isn't empty).

Markus Mützel <mmuetzel>
Project Member
Wed 15 Dec 2021 04:23:50 PM UTC, comment #8: 

@Markus: The "Access = hidden" syntax is not correct.  But, you could answer my question in comment #5 by creating an m-file "return_public.m" which has the following code:

function retval = return_public ()
  retval = 'public';
end

and then changing the code in testclassdef.m to

methods (Access = return_public ())

Does Matlab error for this code which would state that only string literals which are constants at compile-time are allowed?

Rik <rik5>
Project Administrator
Wed 15 Dec 2021 04:11:32 PM UTC, comment #7: 

Oops. Wanted to edit the last message. It should have read:
"An object of that class cannot be created."

The first test was with an empty methods block. In that case, Matlab seems to ignore the syntax error. I'm not sure if it is worth copying that specific behavior...

Markus Mützel <mmuetzel>
Project Member
Wed 15 Dec 2021 04:07:41 PM UTC, comment #6: 

I tested with the following class in Matlab R2021a:

classdef testclassdef

  methods (Access = public)
    function this = testclassdef (varargin)
      a = 1;
    end
  end

  methods (Access = hidden)
    function this = say_hello(this)
      disp('hello');
    end
  end

end

An object of that class can be created. But an error is thrown when trying to access that method:

>> t = testclassdef
Error using testclassdef
Error: File: testclassdef.m Line: 9 Column: 21
'Access' must be public, protected, private or a list of classes.  For more information, see Specify Access to Class Members.

Btw, the error message in Matlab could be more specific. Afaict, `Access` can be set to `public`, `protected`, `private`, or a cell array of meta-classes (like `{?testclassdef2}`).

Markus Mützel <mmuetzel>
Project Member
Wed 15 Dec 2021 03:28:48 PM UTC, comment #5: 

What are the semantics of the "Access = XXX" construct?  If XXX can only be a string literal then we should probably enforce that requirement to prevent weird errors like this.  On the other hand, if desired result is that you can substitute a function which might do some calculations and then return one of "public", "private", or "protected" then we should keep this behavior.

I have to say that the latter case seems quite strange.  It makes sense to me to define classes at compile-time so you know in advance whether a method is going to be public or private.  Using a function would allow the class to change quite fundamentally based on runtime considerations.

I'll add jwe to this bug report for his opinion.  Also, I'll shift this to dev since this won't get decided on in time for 7.1 release.

Rik <rik5>
Project Administrator
Wed 15 Dec 2021 03:40:49 AM UTC, comment #4: 

whoops. 

should this be closed, or is there anything about syntax errors triggering a figure window instead of an error message worth looking into?

Nicholas Jankowski <nrjank>
Project Member
Tue 14 Dec 2021 10:17:00 PM UTC, comment #3: 

Actually, I think the issue is that the Access property is an enumeration that only supports "public", "private", "protected".

"Hidden" is a property which can be "true" or "false".  I think the correct code is

methods (Hidden = true)
endmethods

Rik <rik5>
Project Administrator
Tue 14 Dec 2021 09:44:11 PM UTC, comment #2: 

that seems to make sense.  just tried in another class adding Access = hidden to the properties block and sure enough it pops up a figure window.

Nicholas Jankowski <nrjank>
Project Member
Tue 14 Dec 2021 09:30:20 PM UTC, comment #1: 

Just a guess, hidden() is a function defined in hidden.m which controls the visibility of mesh lines.  If you call hidden with no arguments it creates an empty plot.

It may be that the Octave interpreter sees the word "hidden" and thinks it is a function call rather than a keyword.

Rik <rik5>
Project Administrator
Tue 14 Dec 2021 08:10:54 PM UTC, original submission:  

Tested on Windows in Octave 6.4.0 and 7.0.1 (hg id: 366aa563dd2e)

creating a classdef class, I started getting an odd empty figure window to pop up when creating the object. after some trial and error, I found that having a methods section with (Access = hidden) appears to be the trigger. it seems to not matted what populates the methods, properties, etc.

testclassdef.m:

classdef testclassdef

  methods (Access = public)
    function this = testclassdef (varargin)
      a = 1
    endfunction
  endmethods

#  methods (Access = hidden)
#  endmethods

endclassdef

>> close all;clear all;
>> testclassdef
a = 1
ans =

  testclassdef object with properties:

uncomment the hidden methods section

>> close all;clear all;
>> testclassdef
**empty figure window appears**
a = 1
ans =

  testclassdef object with properties:

Nicholas Jankowski <nrjank>
Project Member

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by rik5
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by nrjank (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only project members can vote.

     

     

     

     

    Follow 8 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2022-03-04 mmuetzel CategoryOctave Function Classdef
    2021-12-16 rik5 StatusInvalid Confirmed
        Summaryclassdef - (Access = hidden) results in spurious figure window classdef (Access = hidden) should have stronger syntax checking
    2021-12-15 rik5 Release7.0.90 dev
        Carbon-Copy- Added jwe
    2021-12-14 rik5 StatusNone Invalid
        Operating SystemMicrosoft Windows Any
    2021-12-14 nrjank Summaryclassdef - methods (Access = hidden) results in spurious figure window classdef - (Access = hidden) results in spurious figure window

    Back to the top


    Powered by Savane 3.9