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: Using transmorphic variables to hold objects in Mata
From
"Joseph Coveney" <[email protected]>
To
<[email protected]>
Subject
st: Using transmorphic variables to hold objects in Mata
Date
Tue, 28 May 2013 00:58:49 +0900
I'm trying to relax static typing for Mata's class programming in order to be
able to interchangeably use objects that have a given method (member function)
but that are not in the same inheritance hierarchy (so-called duck typing). At
first I considered using Mata's transmorphic element type. In interactive mode,
this does work, but it doesn't work elsewhere: although -eltype()-correctly
detects that the variable is holding a class, any attempt to invoke the object's
method results in the same error message, one indicating that Mata is looking
for a -struct- and not finding it. Likewise, if I try using a generic pointer,
-eltype()-again shows that the pointer is pointing to a class definition, yet
attempting to dereference the method (member function) results in an analogous
error message. See the first do-file's result screen below--the problematic
lines of code are commented out along with their corresponding error messages.
It also shows the tactic's working successfully only in interactive mode.
I've managed to accomplish what I want by (i) declaring a pointer that is
defined for an unrelated class that has the given method,(ii) pointing the
pointer to Null, and then (iii) pointing the pointer to the duck-typed object
(which happens to be held temporarily in a transmorphic variable). See the
second do-file's result screen below. The code would do Rube Goldberg proud.
Is anyone aware of a more straightforward approach to this? Mata seems to
recognize when a transmorphic variable is holding an object under some
circumstances, but not under others.
Joseph Coveney
========== First (doesn't work) ===================
. version 12.1
.
. clear *
. set more off
.
. mata:
------------------------------------------------- mata (type end to exit)
----------------------------------------------------------------
: mata set matastrict on
:
: class A {
> public:
> static final void show()
> }
: void function A::show() printf("A\n")
:
: A = A()
: A.show()
A
:
: class B {
> public:
> static final void test()
> }
: void function B::test(transmorphic scalar class_variable) {
> eltype(class_variable)
> /* class_variable.show()
> "type mismatch: exp.exp: transmorphic found where struct expected"
*/
> }
:
: class D {
> public:
> static final void tryem()
> }
: void function D::tryem(pointer() scalar class_ptr) {
> eltype(*class_ptr)
> /* class_ptr->show()
> "type mismatch: exp->exp: transmorphic found where struct expected"
*/
> }
:
:
: void function test() {
> "1"
> class B scalar b
> b.test(A())
> "2"
> class D scalar d
> d.tryem(&A())
> "3"
> transmorphic scalar F
> F = A()
> eltype(F)
> /* F.show()
> "type mismatch: exp.exp: transmorphic found where struct expected"
*/
> "4"
> pointer() scalar a_ptr
> a_ptr = &A()
> eltype(*a_ptr)
> /* a_ptr->show()
> "type mismatch: exp->exp: transmorphic found where struct expected"
*/
> }
:
: test()
1
class
2
classdef
3
class
4
classdef
:
: end
--------------------------------------------------------------------------------
----------------------------------------------------------
.
. exit
end of do-file
============== Second (works) =====================
. version 12.1
.
. clear *
. set more off
.
. mata:
------------------------------------------------- mata (type end to exit)
----------------------------------------------------------------
: mata set matastrict on
:
: class A {
> public:
> static final void show()
> }
: void function A::show() printf("A\n")
:
: class IsNotAnA {
> public:
> static final void show()
> }
: void function IsNotAnA::show() printf("A\n")
:
: class B {
> public:
> static final void test()
> }
: void function B::test(transmorphic scalar is_an_a) {
> pointer(class IsNotAnA scalar) scalar not_an_a_ptr
> not_an_a_ptr = NULL
> not_an_a_ptr = &is_an_a
> not_an_a_ptr->show()
> }
:
: void function test() {
> class B scalar b
> b.test(A())
> }
:
: test()
A
:
: end
--------------------------------------------------------------------------------
----------------------------------------------------------
.
. exit
end of do-file
*
* 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/