bugGNU Octave - Bugs: bug #49421, Can't set properties in a subclass...

 
 

bug #49421: Can't set properties in a subclass after chaining constructors in base class

Submitter:  Ll <pipeng>
Submitted:  Sun 23 Oct 2016 04:47:03 AM UTC
   
 
Category:  Interpreter Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Matlab Compatibility
Status:  Invalid / Not an Octave Bug Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Fri 28 Oct 2016 11:36:27 PM UTC, comment #9: 

The exact error from Matlab when trying to call a base class constructor within itself:


When constructing an instance of class 'derived', the constructor must preserve the class of the returned object


So this is flagged an error in Matlab, in Octave it's permitted but gives questionable results, I think we can consider that working correctly for now.

Mike Miller <mtmiller>
Group Member
Fri 28 Oct 2016 06:47:02 PM UTC, comment #8: 

pipeng: I'm not sure what you are running, but the example for me does the same as the original sym/symfun example:


>> class (derived (1))
ans = base


This is with the single subsasgn() call commented out, which normally causes the error.

Abhinav, re comment #7: This is from testing in Matlab, right?

I think that what you suggest is a really bad workaround for a few reasons, and I think Colin would agree, but we can discuss that on the octsympy issue tracker.

So it seems that there is no Octave bug here, we are compatible with Matlab, and it's just bad practice to have a classdef-based constructor call itself if you are planning on subclassing that object.

Mike Miller <mtmiller>
Group Member
Fri 28 Oct 2016 05:41:58 PM UTC, comment #7: 

@mtmiller The object returned from when the base constructor calls itself it "base". That's why it cannot directly be assigned. But we can copy the properties. 
 
@pipeng Yes I tried in matlab. If octave doesn't support "properties" yet then we can probably have a manual copy of all the properties from sym. This hack can be left till 'properties' is implemented in octave. 
I'll try this for symfun and post on the github PR.

Abhinav Tripathi <genuinelucifer>
Fri 28 Oct 2016 04:56:21 PM UTC, comment #6: 

Hi, i think i found a related thing, i can confirm the example posted here keep the derived subclass, so testing i found, if i don't init the subclass symfun, its created as a sym class....
This don't happen in the examples posted here, but for some reason the sym superclass overwrite the subclass when the subclass is created (you don't need call anything, only set it as a superclass).

The super class sym, the same:
https://github.com/latot/octsympy/blob/bug2/inst/%40sym/sym.m
The subclass symfun:
https://github.com/latot/octsympy/blob/bug2/inst/%40symfun/symfun.m

The subclass only print the class of self:

symfun(1, 2)
ans = sym
ans = (sym) 0

Examples works:

octave:8> class(derived(1))
ans = derived


Thx. Cya.

Ll <pipeng>
Fri 28 Oct 2016 04:23:18 PM UTC, comment #5: 

Hi, i suppose you test it in Matlab? because in octave don't is implemented the properties function:


octave:2> syms a
octave:3> properties(a)
warning: the 'properties' function is not yet implemented in Octave

Please read <http://www.octave.org/missing.html> to learn how you can
contribute missing functionality.
error: 'properties' undefined near line 1 column 1
octave:3> version
ans = 4.3.0+


Ll <pipeng>
Fri 28 Oct 2016 04:09:53 PM UTC, comment #4: 

I think you missed the important question about this example. What is the class of the returned object when the base class constructor calls itself (in Matlab)? Is it a "base" or a "derived"? If it's a "derived" object, then it should have access to all properties of both class definitions.

Mike Miller <mtmiller>
Group Member
Fri 28 Oct 2016 04:04:42 PM UTC, comment #3: 

Apparently we will have to copy each property from base to derived for this to work (just a work-around).. I have to change the derived class to the following then it works perfectly: 
```
classdef derived < base
  properties
    z;
  end
  methods
    function self = derived (a, b, c)
        if nargin<3
            c = 42;
        end
        if nargin<2
            b = pi;
        end
        if nargin<1
            a = 0;
        end
      s = base (a, b);
      self = derived.copy(self, s);
      self = builtin ('subsasgn', self, substruct ('.', 'z'), c);
    end
  end
 
  methods(Static)
       function obj = copy(obj,superobj)
          prop = properties(superobj);
          for i = 1:length(prop)
              obj.(prop{i}) = superobj.(prop{i});
          end
       end
  end
end
```

Abhinav Tripathi <genuinelucifer>
Wed 26 Oct 2016 02:06:52 AM UTC, comment #2: 

I just briefly browsed the Matlab pages on object oriented programming, and they don't show any examples of how to have a base class constructor call itself with a different number or value of arguments. So I don't know whether there is a recommended way to do that or if it's even possible. Someone with Matlab may need to test this and see what is permitted in Matlab, what the right way to do this is, and if Octave needs anything changed.

Mike Miller <mtmiller>
Group Member
Wed 26 Oct 2016 01:49:28 AM UTC, comment #1: 

I am able to reproduce this error with the following minimal example:


$ cat @base/base.m
classdef base < handle
  properties
    x;
    y;
  endproperties
  methods
    function self = base (a, b)
      if (nargin == 0)
        self.x = 0;
        self.y = pi;

      else
        self = base ();
        self.x = a;
        self.y = b;

      endif
    endfunction
  endmethods
endclassdef


$ cat @derived/derived.m
classdef derived < base
  properties
    z;
  endproperties
  methods
    function self = derived (a = 0, b = pi, c = 42)
      self@base (a, b);
      self = builtin ("subsasgn", self, substruct (".", "z"), c);
    endfunction
  endmethods
endclassdef



The key part of this minimal example is that the base constructor overwrites the "self" object with a new instance of type base, when it really should be a derived object. Thus the derived constructor gets back a base object instead of the one it originally started with, and it doesn't have the expected properties.

What does Matlab do? Is there a correct way to do constructor chaining if this is not the right way to do it? Instead of doing something like "self = base ()" should that be "self@base ()" instead? Should both work?

Mike Miller <mtmiller>
Group Member
Sun 23 Oct 2016 04:47:03 AM UTC, original submission:  

Hi, well this i hope this time don't send a wrong issue...

The problem is in some conditions we can't set properties in a subclass, i get this message:


octave:1> symfun('x')
error: subsasgn: unknown property: vars
error: called from
    symfun at line 140 column 9


Sadly i can't get a reduced version of this, because with minimal examples works fine, but in this particular case not.

The branch is here, i try reduce the main file of the subclass:
https://github.com/latot/octsympy/tree/oc

subclass
https://github.com/latot/octsympy/blob/oc/inst/%40symfun/symfun.m

Thx. Cya.

Ll <pipeng>

 

(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 genuinelucifer (Posted a comment)
  • -email is unavailable- added by mtmiller (Posted a comment)
  • -email is unavailable- added by pipeng (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 7 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2016-10-28 mtmiller StatusNeed Info Invalid / Not an Octave Bug
        Open/ClosedOpen Closed
    2016-10-26 mtmiller CategoryNone Interpreter
        Item GroupNone Matlab Compatibility
        StatusNone Need Info
        Operating SystemGNU/Linux Any
        SummaryCan't set properties in a subclass Can't set properties in a subclass after chaining constructors in base class

    Back to the top

    Powered by Savane 3.13-02a9.
    Corresponding source code