#825 closed task (fixed)
How to access global objects
Reported by: | Owned by: | Víctor de Buen Remiro | |
---|---|---|---|
Priority: | highest | Milestone: | OOP Implementation |
Component: | Kernel | Version: | head |
Severity: | major | Keywords: | |
Cc: |
Description
Aunque dentro de la filosofía de programación usando NameBlocks, esto no es una cosa que debería ocurrir, nos encontramos en ocasiones con la necesidad de acceder a un objeto que está en el "espacio de nombres" global.
Por ejemplo, nos encontramos con esa dificultad cuando ya hay un objeto con el mismo nombre en el espacio local de la llamada.
Real A = 1; Real { Real A = 2; Eval("A") // ó Find("A") };
Esto suele ocurrir debido a la costumbre de referirse a un objeto mediante una expresión TOL con la llamada al objeto. El objeto luego se obtiene mediante un Eval de dicha expresión. Esta forma de referirse a un objeto es muy común en el almacenamiento en base de datos.
El problema surge cuando esa evaluación se hace dentro de un contexto (de llamadas a funciones) donde existe una objeto con el mismo nombre que uno de la expresión que se espera global.
Y claro no es fácil evitar usar cualquier nombre que a otro usuario se le haya ocurrido utilizar.
Este problema se puede eliminar ubicando cada cosa en su espacio de nombres correspondiente:
NameBlock MiProjecto = [[ Real A = 1 ]]; Real { Real A = 2; Eval("MiProjecto::A") };
Sin embargo no siempre se hace así.
Mi pregunta es si existe o podría existir alguna manera de obtener un objeto global. Algo como GlobalEval("A")
o Eval("::A")
u otra alternativa.
Change History (11)
comment:1 Changed 15 years ago by
Status: | new → accepted |
---|
comment:2 Changed 15 years ago by
Milestone: | → OOP Implementation |
---|---|
Priority: | normal → highest |
Type: | doubt → task |
Version: | → head |
comment:3 Changed 15 years ago by
Resolution: | → fixed |
---|---|
Status: | accepted → closed |
comment:4 Changed 15 years ago by
Finalmente hasido posible crear el operador monario ::<global_variabla>
Ahora este código funciona perfectamente:
Real G = 1; Set aux = { Real G = 2; [[(Real ::G), G]] }; Real ok.1 = aux[1]==1; Real ok.2 = aux[2]==2;
Hay sólo una excepción. Por ejemplo, este otro código da un error porque no es viable aplicar el operador de búsqueda global al tipo Anything, debido a que es posible crear variables de distinto tipo con el mismo nombre, y todas ellas serían aceptables dando lugar a una ambigüedad dificil de resolver sin pérdida de efciciencia.
Real G = 1; Set fail = { Real G = 2; [[ ::G, G]] };
comment:5 Changed 15 years ago by
Resolution: | fixed |
---|---|
Status: | closed → reopened |
Lo siento, ahora se ha colado otro error en la sintáxis
@<class_name>::<static_member>
Ya había subido los cambios así que se recomienda no actualizarse hasta que se arregle esto.
comment:6 Changed 15 years ago by
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
comment:7 Changed 14 years ago by
Resolution: | fixed |
---|---|
Status: | closed → reopened |
El operador monario ::
no funciona si no se declara el tipo de variable.
El ejemplo propuesto:
Real G = 1; Set fail = { Real G = 2; [[ ::G, G]] };
devuelve:
ERROR: [] Evaluando la expresión ' :: G' No se puede aplicar el operador de búsqueda global ::<variable_global> al tipo Anything Warning: [] La función :: ha fallado en : :: G ...
Parece que ahora es necesario escribir:
... [[ Real ::G, G]] ...
comment:8 Changed 14 years ago by
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
Ya veo que esto se había descubierto y admitido. Me pasa por no leer todo.
Quizá sólo quedaría cambiar el ejemplo en: [wiki/TolOop#Accesoavariablesdel%C3%A1mbitoglobal]
Lo que sería bastante sencillo de hacer es una función
GlobalFind
, pues se trata tan sólo de buscar una variable en el ámbirto global lo cual es facil pues tiene su forma de almacenamiento interna completamente separada del resto.Para evaluar una expresión arbitraria usando sólo variables globales habría que reescribir el evaluador y no le veo mucho sentido.
El operador
::
es binario por lo que el parser no lo admitiría como monario, aunque se puede implementar el mismo sistema que usan los operadores+
y-
. Si es posible hacerlo así eso sería lo más limpio, y si no nos conformaríamos con elGlobalFind