Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • can't drop Mata class with virtual function

    I'm having trouble dropping classes in Mata when they have virtual functions. I've included an example below where I'm not able to drop a parent class, but in another situation I have been unable to drop a child class.

    I'm wondering whether anyone else has run into this problem, whether it's a known issue, whether dropping is disallowed in this situation, etc.

    I am using Stata/IC 13.1 on Windows 7.

    Here is an example from the documentation (help m2_class##def_virtual). The contents of class_example.mata appear at the end of this message. Inside the file a call to drop the parent class leads to an error. By the time that call is reached any explicit references to the class have been dropped.

    Code:
    . mata: mata clear
    
    . run class_example.mata
    classdef animal() in use
    (nothing dropped)
    Just to be sure there are no references, I do mata: mata describe, see nothing else defined, try to drop again, and again get an error.

    Code:
    . mata: mata describe
    
          # bytes   type                        name and extent
    -------------------------------------------------------------------------------
              296   classdef scalar             animal()
               88   void                         ::poke()
               88   void                         ::sound()
    -------------------------------------------------------------------------------
    
    . mata: mata drop animal()
    classdef animal() in use
    (nothing dropped)
    r(310);

    Here are the contents of class_example.mata:

    Code:
    mata
        class animal {
            virtual void sound()
            void         poke()
        }
    
        void animal::sound()
        {
            "Squeak!"
        }
        
        void animal::poke()
        {
            sound()
        }
        
        class cow extends animal
        {
            virtual void sound()
        }
        
        void cow::sound() {
            "Moo!"
        }
        
        cow = cow()
        cow.poke()
        
        // clean up
        mata drop cow
        mata drop cow()
        mata drop animal()
    end
    [edited to use Nick Cox's suggestion regarding bold, below]
    Last edited by James Fiedler; 31 Mar 2014, 11:56.

  • #2
    Congratulations on the first non-administrative post in Statalist after public launch. As you have discovered, the code mark-up is good for blocks of code but not brief mentions. The convention of just putting syntax in bold seems preferable, as in sysuse auto, now that you can do it, to the old -cmdname- convention.

    P.S. Can't help with your serious question.

    Comment


    • #3
      James Fiedler offered the following code

      Code:
      mata
      class animal {
      virtual void sound()
      void poke()
      }
      
      void animal::sound()
      {
              "Squeak!"
      }
      
      void animal::poke()
      {
              sound()
      }
      
      class cow extends animal
      {
              virtual void sound()
      }
      
      void cow::sound() {
              "Moo!"
      }
      
      cow = cow()
      cow.poke()
      
      // clean up
      mata drop cow
      mata drop cow()
      mata drop animal()
      end
      If code is stored in, say, j.do, then we get the following if we run it:

      . do j

      .
      Code:
      . mata
      ------------------------------------------------- mata (type end to exit) ------
      : class animal {
      > virtual void sound()
      > void poke()
      > }
      
      :
      : void animal::sound()
      > {
      >         "Squeak!"
      > }
      
      :
      : void animal::poke()
      > {
      >         sound()
      > }
      
      :
      : class cow extends animal
      > {
      >         virtual void sound()
      > }
      
      :
      : void cow::sound() {
      >         "Moo!"
      > }
      
      :
      : cow = cow()
      
      : cow.poke()
        Moo!
      
      :
      : // clean up
      : mata drop cow
      
      : mata drop cow()
      
      : mata drop animal()
      classdef animal() in use
      (nothing dropped)
      r(310);
      
      : end
      --------------------------------------------------------------------------------
      
      .
      end of do-file
      So I just reproduced the behavior James discovered. Mata claimed it did not drop classdef animal() and indeed it did not,

      Code:
      . mata mata describe
      
            # bytes   type                        name and extent
      -------------------------------------------------------------------------------
                296   classdef scalar             animal()
                 88   void                         ::poke()
                 88   void                         ::sound()
      -------------------------------------------------------------------------------
      So it's a bug we are going to have to track down. In the meantime,a workaround is to type clear mata:

      Code:
      . clear mata
      
      . mata mata describe
      
            # bytes   type                        name and extent
      -------------------------------------------------------------------------------
      -------------------------------------------------------------------------------
      The bug is that Mata thinks the animal.poke() is still in use because mata drop cow() forgot to inform Mata that its function cow.poke was no longer linked to animal.poke().

      This could be very difficult for us to fix. I wonder now if mata drop animal() should not automatically drop any of the structures that extent it. That, I suspect, would be an easier change for us to make.

      -- Bill (StataCorp)





      Comment


      • #4
        Thank you. I will use clear mata for now.

        Comment


        • #5
          I should have said, from the Stata prompt, you can type

          . clear mata
          or, from the Mata prompt, you can type

          : mata clear
          The commands do the same thing.

          -- Bill (StataCorp)

          Comment

          Working...
          X