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 13 years ago

Closed 12 years ago

#1594 closed defect (goodtrick)

Tol no es capaz de aplicar un método a un nameblock cuando es devuelto por una función

Reported by: jmarinero Owned by: Víctor de Buen Remiro
Priority: normal Milestone: Mantainance
Component: OOP Version: 3.1
Severity: normal Keywords:
Cc:

Description

DevuelveNameBlockMasReciente es una función que recibe como argumento un conjunto de objetos forecast y que devuelve un NameBlock forecast de acuerdo a un criterio (que sea el más reciente)

Si ejecuto

DevuelveNameBlockMasReciente(Set ModCliNuA   )

me devuelve un NameBlock sin problema alguno cuya ruta, por cierto, es:

MMS::Container::GetForecast(1)

Si yo ahora ejecuto:

MMS::Container::GetForecast(1)::GetModel.Forecast(?)

no hay ningún problema. Obtengo el nameblock deseado sin problema alguno.

Pero si ejecuto:

DevuelveNameBlockMasReciente(Set ModCliNuA)::GetModel.Forecast(?)

lo que obtengo es un warning:

Warning: [2] La función :: ha fallado en : 
DevuelveNameBlockMasReciente(Set ModCliNuA)::GetModel.Forecast(?)

He probado con varias combinaciones de paréntesis rodeando el nameblock devuelto por la función a la que quiero aplicar el ::getmodel, pero no hay forma.

(DevuelveNameBlockMasReciente(Set ModCliNuA))::GetModel.Forecast(?)

produce exactamente el mismo resultado.

He probado con:

(  [[DevuelveNameBlockMasReciente(Set ModCliNuA)]])[1]::GetModel.Forecast(?)

Obteniendo el error:

ERROR: [10] Element (ó [ ] ):Indice de conjunto inválido, debe ser Real o Text

Y si rodeo con paréntesis la expresión anterior:

(( [[DevuelveNameBlockMasReciente(Set ModCliNuA)]])[1])::GetModel.Forecast(?)

obtengo el warning

Warning: [15] La función :: ha fallado en : 
((SetOfAnything[[DevuelveNameBlockMasReciente(Set ModCliNuA)]])[[1])::GetModel.Forecast(?)

Curiosamente, si accedo directamente el elemento 1 del conjunto ModCliNuA en vez de utilizar la función DevuelveNameBlockMasReciente sí funciona:

(ModCliNuA[1])::GetModel.Forecast(?)

y produce el resultado deseado.

El problema es que en mi caso no siempre quiero acceder al elemento número 1 del conjunto. La forma que tengo de decidir el elemento al que quiero acceder es la función DevuelveNameBlockMasReciente.

Tampoco puedo utilizar

MMS::Container::GetForecast(1)::GetModel.Forecast(?)

porque igual que no funciona el ::GetModel tampoco funciona el ::GetRoute y no puedo obtener su ruta

Por si fuera útil, el código de esta función es el siguiente. Lo que hace es ordenar en orden alfabético inverso por el nombre de los nameblocks en el conjunto que se le pasa y devolver el primero de la lista:

NameBlock DevuelveNameBlockMasReciente(Set setNameBlocks)
  {
    //Ordeno el conjunto por orden alfabético inverso
    Set ord = Sort(Set setNameBlocks, Real(NameBlock k1_, NameBlock k2_)
      {
        Text k1 = Name(NameBlock k1_);
        Text k2 = Name(NameBlock k2_);
        Real 0 + 1 * (Text k1 < Text k2) - 1 * (Text k2 < Text k1)
      });
    //Me quedo con el primero elemento, que (a no se que cambien la nomenclatura 
    //en los nombres de los objetos) será el objeto forecast más reciente
    NameBlock ord[1]
  };

Gracias, un saludo.

Change History (5)

comment:1 Changed 13 years ago by Pedro Gea

El problema también puede reproducirse con el siguiente código:

NameBlock a = [[
  Real DevuelveUno(Real void) { 1 }
]];
NameBlock DameA(Real void) { a };

Real DameA(?)::DevuelveUno(?);
// -> Warning: [] La función :: ha fallado en : 
//    DameA(?)::DevuelveUno(?)

comment:2 Changed 13 years ago by Pedro Gea

Un modo de evitar el error es construir una referencia auxiliar del NameBlock y luego usarla:

// El siguiente código sustituiría a: Real DameA(?)::DevuelveUno(?);
Real {
  NameBlock auxiliar = DameA(?);
  auxiliar::DevuelveUno(?)
};

Nótese que NameBlock auxiliar es una referencia al mismo objeto NameBlock a y no se construye una nueva instancia sino que auxiliar es, por así decirlo, otro NameBlock que accede al mismo contenido que NameBlock a.

comment:3 Changed 13 years ago by Pedro Gea

En el caso que se presenta, la solución sería:

Anything {
  NameBlock auxiliar = DevuelveNameBlockMasReciente(Set ModCliNuA);
  auxiliar::GetModel.Forecast(?)
}

comment:4 Changed 13 years ago by Pedro Gea

Habría que discernir si el problema se produce por una limitación en TOL o por un uso inadecuado de la sintaxis de TOL, y ver si tiene fácil solución.

comment:5 Changed 12 years ago by Víctor de Buen Remiro

Resolution: goodtrick
Status: newclosed

Yo no he sido capaz de encontrar ninguna solución satisfactoria para este problema que ya conocía desde hace tiempo.

Me temo que es obligatorio usar la referencia tal y como propones y como yo he hecho siempre.

Note: See TracTickets for help on using tickets.