bugGNU Octave - Bugs: bug #65667, classdef calls overloaded function...

 
 

bug #65667: classdef calls overloaded function struct() rather than builtin struct()

Submitter:  Tibor Auer <tiborauer>
Submitted:  Wed 01 May 2024 05:39:21 PM UTC
   
 
Category:  Octave Function Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Regression
Status:  Ready For Test Assigned to:  None
Originator Name:  Tibor Auer Open/Closed:  * Open
Release:  * 9.1.0 Operating System:  * Any
Fixed Release:  9.2.0 (current stable) Planned Release:  9.2.0 (current stable)
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Thu 16 May 2024 03:40:23 PM UTC, comment #12: 

Thank you, Rik!

Tibor Auer <tiborauer>
Thu 16 May 2024 03:35:01 PM UTC, comment #11: 

I checked in a fix for this here https://hg.savannah.gnu.org/hgweb/octave/rev/97b44c6e3e35.

I made the change on the stable branch since this is a regression.  Ideally, this will be part of the 9.2 bug fix release which is imminent.  In any case, it is just a small change to an m-file so you could download the file inputParser.m from the Mercurial repository and copy the file to your installation to see the change.

Marking as Ready for Test.

Rik <rik5>
Group administrator
Thu 16 May 2024 03:11:46 PM UTC, comment #10: 

Thank you, Nicholas, for both the clarification of the guidelines and the completion of the bug report.

Tibor Auer <tiborauer>
Thu 16 May 2024 02:49:17 PM UTC, comment #9: 

FYI - in general when we're asking what matlab does we are NOT asking anyone to check the code, even when it is plaintext m code, just to check what the matlab output is, if it produces an error, etc.  It is very necessary that anyone contributing to octave not look at matlab sourcecode.

so your response about the output is sufficient. 

just confirming with matlab 2024a:

>> p = inputParser ()

p =

  inputParser with properties:

       FunctionName: ''
      CaseSensitive: 0
      KeepUnmatched: 0
    PartialMatching: 1
       StructExpand: 1
         Parameters: {1×0 cell}
            Results: [1×1 struct]
          Unmatched: [1×1 struct]
      UsingDefaults: {1×0 cell}

>> p.addParameter ('arg1',testClass)
>> p

p =

  inputParser with properties:

       FunctionName: ''
      CaseSensitive: 0
      KeepUnmatched: 0
    PartialMatching: 1
       StructExpand: 1
         Parameters: {'arg1'}
            Results: [1×1 struct]
          Unmatched: [1×1 struct]
      UsingDefaults: {1×0 cell}

>>


vs a recent octave stable build:

>> p = inputParser ()
p =

inputParser object with properties:

   FunctionName    : ""
   CaseSensitive   : false
   KeepUnmatched   : false
   PartialMatching : true
   StructExpand    : true

Defined parameters:

   {}

>> p.addParameter ('arg1', testClass)
error: struct: function called with too many inputs
error: called from
    struct
    addParameter at line 369 column 31


Nicholas Jankowski <nrjank>
Group Member
Thu 16 May 2024 07:26:10 AM UTC, comment #8: 

That is correct, Rik! Thank you!

I am afraid I don't know how to check MATLAB's implementation because the code of its built-ins is not available; however, it has no issue with the test code.

Also, OCTAVE did use dot notation until 9.1.0.

Tibor Auer <tiborauer>
Wed 15 May 2024 09:06:38 PM UTC, comment #7: 

I'm guessing that this bit of code will exercise the problem.


p = inputParser ();
p.addParameter ('arg1', testClass)


I can see a way to re-code inputParser.m to not use struct() and use dot-notation instead.  But, I'd like confirmation about what Matlab does.

Rik <rik5>
Group administrator
Wed 15 May 2024 05:47:48 PM UTC, comment #6: 

No offense taken :-)

Right then, would you have some example test code for inputParser to try in Matlab and Octave, so that your problem can be debugged by the devs here?

Philip Nienhuis <philipnienhuis>
Group Member
Wed 15 May 2024 05:21:05 PM UTC, comment #5: 

Hi Philip,
The last comment was meant to you, rather than Rik. Sorry!

Tibor Auer <tiborauer>
Wed 15 May 2024 05:19:37 PM UTC, comment #4: 

Thank you, Rik!

As I mentioned, my actual issue is not with the struct function but with the inputParser (lines 365-370 in Octave 9.1.0), which has been updated from dot notation to calling the struct function.

I am afraid I cannot check the MATLAB implementation (because it is not open source), but I can tell it accepts my object with an overloaded struct() method. So, the MATLAB incompatibility may not lie in the struct function but in the inputParser since Octave 9.1.0.

Tibor Auer <tiborauer>
Wed 15 May 2024 04:52:33 PM UTC, comment #3: 

Matlab r2020b:

>> format compact
>> c = testClass ()
c =
  testClass with no properties.
>> s = struct('p', c)
Error using testClass/struct
Too many input arguments.
>> s.p = c
s =
  struct with fields:

    p: [1×1 testClass]

so it looks the same and Octave behaves Matlab-compatible.

Philip Nienhuis <philipnienhuis>
Group Member
Sat 04 May 2024 07:28:33 PM UTC, comment #2: 

Thank you, Rik!

I am afraid the workaround is not an option because, as I mentioned in the beginning, it affects the updated inputParser function (lines 365-370), which, indeed, used the dot notation workaround in previous versions.

Tibor Auer <tiborauer>
Sat 04 May 2024 02:54:30 PM UTC, comment #1: 

It helps to surround code examples in a bug report with the verbatim tag so they are rendered in a fixed-width font.

The issue seems to be that testClass overloads the "struct" function with its own definition and when


struct ("p", c)


is called it is the overloaded version of the function from testClass which expects only one input which is called.

That is probably a bug, but it would be useful if someone could test this under Matlab.  I've re-titled the bug report and marked it as Confirmed.

For the time being, there are lots of workarounds and you should use one of those.

Workaround #1: dot notation


s.p = c;


Workaround #2: use builtin() to call base function rather than overload


s = builtin ('struct', 'p', c);


Workaround #3: use a function which isn't overloaded.


s = struct ();
s = setfield ('p', c);



Rik <rik5>
Group administrator
Wed 01 May 2024 05:39:21 PM UTC, original submission:  

9.1.0 has updated parameter specification and replaced struct specification field-by-field with calling the struct function (lines 365-370). Unfortunately, it prevents me from specifying my custom class, which has a struct method as a default parameter.

After some digging, I have found that it is due to the struct function, which does not accept such class as a field value.

Minimum code:
testClass.m
  classdef testClass
    methods
      function p = testClass ()
      end

      function s = struct(this)
        s = 12;
      end

    end
  end

>> c = testClass()

c =

  testClass object with properties:


>> s = struct("p",c)

error: struct: function called with too many inputs
error: called from
    struct

>> s.p = c

s =

  scalar structure containing the fields:

    p =

      testClass object with properties:

Tibor Auer <tiborauer>

 

(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 rik5 (Posted a comment)
  • -email is unavailable- added by tiborauer (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 6 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2024-05-16 rik5 Item GroupUnexpected Error or Warning Regression
        StatusConfirmed Ready For Test
        Fixed ReleaseNone 9.2.0 (current stable)
        Planned ReleaseNone 9.2.0 (current stable)
    2024-05-04 rik5 StatusNone Confirmed
        SummaryinputParser does not accept object with struct method as default value classdef calls overloaded function struct() rather than builtin struct()

    Back to the top

    Powered by Savane 3.13-4b48.
    Corresponding source code