Dear Glenn,
I can add that there is a related problem with plugins, which plugins
writers must be aware of:
Suppose a Stata program calls a plugin with variables X Y Z in varlist
and vars T X Y U Z in memory
Plugin will receive this memory arrangement: X Y Z [. .] here
variables in [] are inaccessible in the plugin body and their order in
memory is undetermined
Suppose the plugin stores the var indices and returns control to
Stata, while remaining in memory (say leaving a form with some
controls).
Upon receiving control Stata restores variables order to T X Y U Z
If now plugin receives control (say the user clicks the button on the
plugin's form), it will confuse the variable indices (e.g. when
requesting the first variable, the plugin will now get T instead of
X).
This was discovered accidentially, when a procedure called
interactively (by clicking a button) and programmatically - upon
plugin load/start yielded different results.
Hence two points:
1) if a plugin uses forms - it must be modal or not access Stata data
after it returns control to Stata (this is the safest solution)
2) an advice from StataCorp (thanks to Kevin Crow) was to call the
plugin without varlist, and pass variables' names to it, then use
stfindvar() to determine the index of the required variable. If this
is done every time before accessing the data, it seems to be a good
solution. (in this case all variables are included into varlist, their
order corresponds to the current in-memory order, and they are all
accessible).
Hope this helps,
Sergiy Radyakin
On Sun, Mar 8, 2009 at 3:29 PM, Glenn Goldsmith
<[email protected]> wrote:
> Dear list,
>
> I think I may have found a problem (dare I call it a bug?) in the way mata's
> -st_varindex()- and -st_addvar()- commands interact with the e(sample)
> function returned by Stata regression commands.
>
> The code below demonstrates the problem. The following is my guess as to
> what is going on:
>
> 1. Following a regression command, Stata creates a variable called "(e)",
> which is invisible in Stata, but is visible in Mata.
>
> 2. If -st_addvar()- is called when the "(e)" variable is in memory, it
> simply adds what it is asked to add after the "(e)", and returns the indices
>
> 3. If -st_varindex()- is called when the "(e)" variable is in memory, it
> reorders the variables, such that "(e)" is moved to the last variable
> position, and then returns the index of the requested variable.
>
> The upshot of this is that, with "(e)" in memory, if you add variables and
> obtain their indices using -st_addvar()-, these indices are invalidated by a
> subsequent call to -st_varindex(). This isn't actually much of a problem in
> the toy code below, because -st_varindex()- has just given you the right
> indices anyway. But it's more or an issue if you use -st_varindex()- to
> obtain the index of an unrelated variable, and don't realize that it's
> reordering the variables, which is how the problem initially arose for me.
>
> Workarounds are easy enough, once you're aware of the issue, and perhaps
> there is a reason why -st_varindex()- needs to reorder things. But if so,
> shouldn't -st_addvar()- do the same, so that this sort of inconsistency
> doesn't arise?
>
> ************ Begin Code ************
> clear
> sysuse auto
> qui reg price weight mpg
> mata:
> st_varname(range(1,13,1)')
> st_addvar("byte","newvar")
> st_varname(range(1,14,1)')
> st_varindex("newvar")
> st_varname(range(1,14,1)')
> end
> ************ End code **************
>
> Best wishes,
>
> Glenn.
>
> *
> * For searches and help try:
> * http://www.stata.com/help.cgi?search
> * http://www.stata.com/support/statalist/faq
> * http://www.ats.ucla.edu/stat/stata/
>
*
* For searches and help try:
* http://www.stata.com/help.cgi?search
* http://www.stata.com/support/statalist/faq
* http://www.ats.ucla.edu/stat/stata/