close Warning: Can't synchronize with repository "(default)" (/var/svn/tolp does not appear to be a Subversion repository.). Look in the Trac log for more information.

Opened 15 years ago

Closed 14 years ago

Last modified 13 years ago

#825 closed task (fixed)

How to access global objects

Reported by: pgea@… 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 Víctor de Buen Remiro

Status: newaccepted

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 el GlobalFind

comment:2 Changed 15 years ago by Víctor de Buen Remiro

Milestone: OOP Implementation
Priority: normalhighest
Type: doubttask
Version: head

comment:3 Changed 15 years ago by Víctor de Buen Remiro

Resolution: fixed
Status: acceptedclosed

(In [1869]) Fixes #825

comment:4 Changed 15 years ago by Víctor de Buen Remiro

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 Víctor de Buen Remiro

Resolution: fixed
Status: closedreopened

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 Víctor de Buen Remiro

Resolution: fixed
Status: reopenedclosed

(In [1870]) Fixes #825

comment:7 Changed 14 years ago by Pedro Gea

Resolution: fixed
Status: closedreopened

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 Pedro Gea

Resolution: fixed
Status: reopenedclosed

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]

comment:10 Changed 14 years ago by Víctor de Buen Remiro

Hecho

comment:11 Changed 13 years ago by Víctor de Buen Remiro

(In [4086]) refs #825
upgrading test

Note: See TracTickets for help on using tickets.