bugGNU Octave - Bugs: bug #42620, exist() does not use...

 
 

bug #42620: exist() does not use "class" argument

Submitter:  Rik <rik5>
Submitted:  Wed 25 Jun 2014 08:57:03 PM UTC
   
 
Category:  Octave Function Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Matlab Compatibility
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * GNU/Linux
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Mon 22 Nov 2021 07:27:20 PM UTC, comment #10: 

The note in Matlab documentation is "MATLAB does not examine the contents or internal structure of a file and relies solely on the file extension for classification.".

Now, maybe that is out of date and they actually do some parsing.  For "inputParser", the "class" argument changes the output value from 2 to 8.  It does not have that effect on a normal m-fil.  I tried


exist ('ls')
exist ('ls', 'class')


and the first invocation returns 2 while the second invocation returns 0.

If there is more work to be done on exist() then I would file a different bug report about it.

For the specific case of "+foopkg/foopkg.m" and a file "foopkg.m" elsewhere in the function search list Matlab seems to say that the return value is decided by order in the path().

Rik <rik5>
Group administrator
Mon 22 Nov 2021 07:05:42 PM UTC, comment #9: 

I'm confused as to how Matlab can know to return 8 for


exist ('inputParser', 'class')


without looking inside the inputParser.m file.  Does it also return 8 for


exist ('not_a_classdef_function', 'class')


?

In earlier versions, we did ask the symbol table to find functions.  But in the current definition of symbol_exist in variables.cc, it seems that we are only checking the symbol table for variables or command-line functions (which have already been parsed successfully or they wouldn't exist in the function table).  In earlier versions, we did ask the symbol table to find functions.  Everything else appears to use the load path.

If not specifically looking for a file, it seems to me that


exist foopkg.m


could be either a function "m" in the package "foopkg" or the file "foopkg.m".  If both exist, I suppose we should be finding the package function first?  So yes, we probably need to update the rules for parsing these names.  Are similar changes needed for the which function?  Maybe we can share some code for these jobs.

John W. Eaton <jwe>
Group administrator
Sat 20 Nov 2021 06:41:04 PM UTC, comment #8: 

When a classdef m-file exists Matlab returns 2 (because it is an m-file) unless the programmer specifically narrows the search to classdef files.


exist inputParser
ans = 2
exist ('inputParser', 'class')
ans = 8


I recreated this behavior in Octave for compatibility.

On the larger question of parsing of the file, this is a problem for Octave but not for Matlab.  Matlab specifically says in the documentation that they make no determination about the viability of the file.  Octave's exist function works differently because it searches through the symbol table which means functions have to have been parsed correctly.  There is already a warning in the documentation for exist that bad .mex or .oct files can crash Octave because exist() will try to query them.

Finally, "container.Map" is a problem for Octave because of the algorithm used for exist which tries to strip off an extension on the name of a file.  This works fine for things like "ls.m" or "function.mex".  In this case, however, I believe Octave is stripping what it views as the extension "Map" and then querying the symbol table for a function "container" which does not exist.

Rik <rik5>
Group administrator
Sat 20 Nov 2021 04:58:16 AM UTC, comment #7: 

I added support for the "class" argument in this changeset: http://hg.savannah.gnu.org/hgweb/octave/rev/b568c29bb5be.

Marking as Ready for Test.

Rik <rik5>
Group administrator
Sat 20 Nov 2021 04:15:32 AM UTC, comment #6: 

created a test class

brokenclass.m:

classdef brokenclass
  a =
end



>> brokenclass
Error using brokenclass
File: brokenclass.m Line: 2 Column: 1
Invalid expression. Check for missing multiplication
operator, missing or unbalanced delimiters, or other syntax
error. To construct matrices, use brackets instead of
parentheses.
>> exist('brokenclass')
ans =
     2


deleted the a = line:


>> brokenclass
ans =
  brokenclass with no properties.
>> exist('brokenclass')
ans =
     2


I'm not sure what it needs to see to make it exist output an 8.

Nicholas Jankowski <nrjank>
Group Member
Sat 20 Nov 2021 03:26:11 AM UTC, comment #5: 

Maybe we just need a function that can extract the first token from a .m file.  If it is CLASSDEF, then return 8, otherwise 2?

We could check whether Matlab does this or actually parses the file and requires it to be a valid classdef file by creating a file that has syntax errors after the initial classdef token.  If it still returns 8 with the syntax errors, we probably just need to check for the initial token value.  Otherwise, we may need to parse the entire file and only return 8 if the classdef file can be parsed without error.

John W. Eaton <jwe>
Group administrator
Sat 20 Nov 2021 02:22:57 AM UTC, comment #4: 

Octave should return 8 for classdef m-files to be compatible with Matlab.  The function to edit is symbol_exist in variables.cc.  There are two locations where "return 2;" is used.  For these two cases Octave needs to further distinguish between an ordinary file and a classdef file.  Probably that means querying the symbol table as is done in which().

Rik <rik5>
Group administrator
Wed 08 Sep 2021 06:50:37 PM UTC, comment #3: 

updating for v6.3.0:

old style class:

>> exist('ftp')
ans = 2


classdef style class:

>> exist('inputParser')
ans = 2


Octave seems to have trouble finding containers.Map:

>> exist('containers.Map')
ans = 0

>> which containers.Map

>> A = containers.Map()
A =

  containers.Map object with properties:

    Count     : 0
    KeyType   : char
    ValueType : any



Matlab 2021a:

>> exist('ftp')
ans =
     2
>> exist('inputParser')
ans =
     2
>> exist('containers.Map')
ans =
     8



it seems to not matter so much if it's old style or classdef.  I created two dummy classes.  myclassdef and @myoldclass/myoldclass.m

with both in the path:



Matlab 2021a:


>> exist(myoldclass)

ans =
     2

>> exist('myclassdef')
ans =
     2



same results in Octave. not sure what sets containers.Map apart in Matlab.

Nicholas Jankowski <nrjank>
Group Member
Wed 17 Apr 2019 09:57:26 PM UTC, comment #2: 

It seems that exist returns 8 only for classdef.  On Matlab,


x = exist ('containers.Map')
x = 8
y = exist ('ftp')
y = 2


The return value 2 just means an m-file exists on the path, nothing special.

Rik <rik5>
Group administrator
Wed 17 Apr 2019 06:22:04 PM UTC, comment #1: 

Does Matlab's exist function return 8 for both classdef and legacy classes, or just classdef?

John W. Eaton <jwe>
Group administrator
Wed 25 Jun 2014 08:57:03 PM UTC, original submission:  

exist() has not been extended on the classdef branch (version 4.2) to return 8 when the input is a class name.

Rik <rik5>
Group administrator

 

(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 nrjank (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by amro_octave
  • -email is unavailable- added by rik5 (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 group members can vote.

     

    Follow 5 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2021-11-22 rik5 StatusReady For Test Fixed
        Open/ClosedOpen Closed
    2021-11-20 rik5 StatusConfirmed Ready For Test
    2019-04-17 rik5 StatusNone Confirmed
    2016-12-09 amro_octave Carbon-Copy- Added amro_octave

    Back to the top

    Powered by Savane 3.13-d3ae.
    Corresponding source code