Announcement

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

  • Persistent class objects with ado programs

    I'm attempting to create an -ado- program whose purpose is to create an instance of a class and then have other -ado- programs interact with that class instance to create things like reports, etc. Is the only way to have the class instance persist to declare it in a .mata file outside of the -ado- file?

  • #2
    Originally posted by Leonardo Guizzetti View Post
    Is the only way to have the class instance persist to declare it in a .mata file outside of the -ado- file?
    If you mean by "declare" to instantiate an object of the class, then no. But you will have to define the class in a location where all of the referring ado-file programs can see its definition so that they're all talking about the same thing. You can do that in a .mata file and use -include- in all of the ado-programs that you want to make a reference to that type of class. You can then pass around a Mata object that's been instantiated in one ado-file program to different ado-file programs via a Mata external global variable.

    I show an example below. In the example I have a do-file (as a test harness) call two ado-file programs that make use of a common Mata object (a Football). The first (-called.ado-) instantiates an object of the Football class and the second (-caller.ado-) receives it via a Mata external global variable and proves its identity. It's not an absolute requirement, but in the example below I use Stata's -tempfile- in order to create a unique name for the global variable in order to help avoid the usual problems incumbent on the use of global variables. And I pass the name explicitly as an argument to the different ado-file programs via an option.

    Class definition in the .mata file to be included
    Code:
    *! football.mata
    
    version 17.0
    
    mata:
    mata set matastrict on
    
    class Football {
        private:
            string scalar id
            void new()
        public:
            final void showID()
    }
    void function Football::new() id = sprintf("%tcCCYY-NN-DD_HH:MM:SS.sss", now())
    void function Football::showID() printf("%s\n", id)
    
    end
    First ado-file program (instantiates an object of the Football class)
    Code:
    *! called.ado
    program define called
        version 17.0
        syntax , Classname(string)
    
        mata: Called::beginHere()
    end
    
    version 17.0
    
    include football.mata
    
    mata:
    mata set matastrict on
    
    class Called {
        public:
            static final void beginHere()
    }
    void function Called::beginHere() {
    
        pointer() scalar p
        p = crexternal(st_local("classname"))
    
        // Instantiate it
        class Football scalar f
    
        // Show its identity at instantiation
        printf("At instantiation: ")
        f.showID()
    
        // Now assign it
        *p = f
    }
    
    end
    Second ado-file program (receives a Football object and proves its identity)
    Code:
    *! caller.ado
    program define caller
        version 17.0
        syntax , Classname(string)
    
        mata: Caller::beginHere()
    end
    
    version 17.0
    
    include football.mata
    
    mata:
    mata set matastrict on
    
    class Caller {
        public:
            static final void beginHere()
    }
    void function Caller::beginHere() {
    
        pointer(class Football scalar) scalar p
        p = findexternal(st_local("classname"))
    
        printf("After passing to another ado-file program\n")
        p->showID()
    
    }
    
    end
    Test harness
    Code:
    *! test.do
    
    version 17.0
    
    clear *
    
    // Get unique name for the Mata external global variable
    tempname football
    
    // Create the object ("Football") to be shared between ado-file programs
    called , c(`football')
    
    // Share the Mata object and prove it is the same
    caller , c(`football')
    
    // Clean up
    mata: rmexternal("`football'")
    
    exit
    Worked illustration
    .
    . version 17.0

    .
    . clear *

    .
    . // Get unique name for the Mata external global variable
    . tempname football

    .
    . // Create the object ("Football") to be shared between ado-file programs
    . called , c(`football')
    At instantiation: 2021-09-27 11:49:11.000

    .
    . // Share the Mata object and prove it is the same
    . caller , c(`football')
    After passing to another ado-file program
    2021-09-27 11:49:11.000

    .
    . // Clean up
    . mata: rmexternal("`football'")

    .
    . exit

    end of do-file


    .


    Creation of the -tempname- can be done entirely within Mata, of course, using -st_tempname()-.

    Comment


    • #3
      Thank you Joseph Coveney, and especially for a small working example. This should indeed help me for what I am trying to do.

      Comment

      Working...
      X