Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Variable Scoping
Message
De
23/12/2003 16:16:22
 
 
À
23/12/2003 15:25:04
Information générale
Forum:
Visual FoxPro
Catégorie:
Programmation Orientée Object
Divers
Thread ID:
00861687
Message ID:
00861752
Vues:
24
> > This is an insidious (and rather silly) bug, and as far as I can see it is
> > the only way how a global var can be masked out of existence (rather than
> > hidden by symbols with the same name that are closer in scope).

> It's exactly the same thing. Look at what happens in the debugger, and
> pause in the called routine and do a DISPLAY MEMORY from the command window.

Well, we know that Fox hides the global variable but this behaviour does not make sense at all, and it is completely different from the hiding implied by normal scoping rules.

The fact that a symbol in an inner scope hides symbols with the same name in outer scopes is just how scoped names are expected to work, it is just a result of the name having a different meaning within the inner scope (the name simply refers to a different entity, at least potentially). However, normal name scoping also implies that inner scopes can only add or redefine names, but it is not possible to remove names - which is exactly what the bug does.

Furthermore, most coding standards proscribe special names for the few globals that are permitted to exist (like prefixing such names with "g_"), and so it is simply not possible for local names to hide global names in code written to conform with such a standard.

The consequence of the bug is that special consideration/coding is required whenever globals must be passed by reference, like using an intermediary local variable or documenting why the temporary 'non-existence' of the global var is not expected to cause problems with the called code (which presumes complete knowledge of the called code, including any calls to other subsystems that this code may make, and which creates nice Heisenbug potential for maintenance).

Here's some repro code that demonstrates how this can byte you even if you are only a little bit guilty:
release g_uTest
public  g_uTest

sele sele("orders")
use home(2)+"\Northwind\orders" noup agai orde customerid
brow last nowa

sele sele("customers")
use home(2)+"\Northwind\customers" noup agai
set rela to rela_(customerid) into orders in customers
brow last nowa

b0rken_(@m.g_uTest)

set rela off into orders in customers
rele g_uTest

function b0rken_ (ruParam)
   ? type([m.g_uTest]), program()
   set date dmy  && this causes any active relations to 'fire'

function rela_ (uExpr)
   ? type([m.g_uTest]), program()
   return m.uExpr
The output:
L RELA_
U B0RKEN_
U RELA_
U RELA_
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform