Bookmark and Share

Notice: On April 23, 2014, Statalist moved from an email list to a forum, based at statalist.org.


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

st: Re: reciprocal references between classes in Mata


From   [email protected]
To   [email protected]
Subject   st: Re: reciprocal references between classes in Mata
Date   Fri, 06 Sep 2013 15:22:40 -0500

Phil Schumm<[email protected]> asks how to define two Mata classes with 
circular dependency:

> At the risk of drawing scorn from the Mata cognescenti (I feel like I'm
> going to realize that the answer to this question is obvious as soon as I
> click "Send"), consider the following (simplified) example:
>
>
>    class Results {
>        real scalar                                 primary_outcome
>        pointer(class Study scalar) scalar          study
>        void                                        myfunc()
>    }
>
>    void Results::myfunc()
>    {
>        study->type
>    }
>
>    class Study {
>        string scalar                               type
>        class Results scalar                        results
>        void                                        new()
>    }
>
>    void Study::new()
>    {
>        type = "RCT"
>        results = Results()
>        results.study = &this
>    }
>
>
> As you can see, I have a Study class, which has as an attribute an instance
> of a Results class.  In addition, there are behaviors I'd like to implement
> for the results that depend on features of the study (e.g., in this case,
> the study type).  The problem is, I can't figure out the best way (or even
> any way) to refer to the study from within the results instance.
>
> Clearly what I've written above won't work, because the compiler won't
> recognize the Study class when compiling Results (and I can't switch the
> order of Results and Study, since that will cause the same problem in
> reverse).  I feel like I should be able to declare the Study class (i.e.,
> like in C) so that the compiler knows a definition is coming, but I don't
> know how to do that in Mata.
>

The trick here is to realize Mata does not require the class member function
definition to immediately follow the class definition, you may delay the class
member function definition as much as you want. The following code should do
what Phil wants:

//-----------------------------------------------------------------------
cscript
mata:

mata clear	

class Results {
    real scalar                         primary_outcome
    pointer(class Study scalar) scalar  study
    void                                myfunc()
}

class Study {
    string scalar                       type
    class Results scalar                results
    void                                new()
}

void Results::myfunc() {
    printf("The study type = %s\n", study->type)
}

void Study::new() {
    type = "RCT"
    results = Results()
    results.study = &this
}

void testit() {
    class Results scalar a
    class Study scalar b
    a.study = &b
    a.myfunc() ;
}

testit()	

end
//-----------------------------------------------------------------------

Hua
[email protected]

*
*   For searches and help try:
*   http://www.stata.com/help.cgi?search
*   http://www.stata.com/support/faqs/resources/statalist-faq/
*   http://www.ats.ucla.edu/stat/stata/


© Copyright 1996–2018 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   Site index