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

Last modified 13 years ago

#1428 closed doubt (fixed)

Uso de PutName en ciclos

Reported by: Pedro Gea Owned by: Víctor de Buen Remiro
Priority: highest Milestone: Mantainance
Component: Kernel Version:
Severity: critical Keywords:
Cc:

Description

El método más común cuando se quiere poner un nombre a la salida de una función es usar PutName. Sin embargo, este método no funciona como se espera en algunas circunstancias, provocando el uso mecanismos alternativos que crean copias.

El crear copias de determinados objetos reduce la eficiencia de los métodos (véase #1426) por lo que parece conveniente buscar algún método para esquivarlo.

Consideremos por ejemplo la función:

Matrix Fun(Matrix m) {
  Real i = MatDat(m,1,1);
  If(i > 5, PutName("V."<<i, m), {
    Matrix m2 = m * 2;
    PutName("V."<<i, m2)
  })
};

que duplica una matriz (en determinados casos) y cambia su nombre.

Esta función no actúa como se espera, y no cambia el nombre de aquellos objetos que devuelve tal y como recibe. Por ejemplo:

Set matrices = For(1, 10, Matrix (Real i) {
  Eval("Matrix "<<Char(64+i)<<" = Row(i)")
});
Set EvalSet(matrices, Fun);

¿Es esto un error en el funcionamiento de PutName? ¿hay alguna alternativa, dejando de un lado la conveniencia o no de hacerlo así?

Otras variantes que sí funcionan (pero que hacen una copia) y que se están usando en lugar de PutName son:

Anything PutName2(Text name, Anything a) {
  Anything a_ = a;
  PutName(name, a_)
};

Anything PutName3(Text name, Anything a) {
  Eval("Anything "<<name<<" = a")
};

Change History (6)

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

(In [4108]) Refs #1428

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

Yo no me había percatado de ese problema nunca porque suelo usar el PutName en un ciclo For posterior pero creo que es fácil de resolver.

Hay una clase plantilla BFunArgObject que se usa para renombrar los argumentos de las funciones mediante un objeto referencial que sobrecarga algunos operadores como el

const BText& Name () const { return(this->GetResult()->Name()); }

Creo que simplemente habría que hacer lo mismo con el PutName porque ahora mismo, en lugar de cambiar sobre el objeto referenciado, está cambiando el del objeto referenciador.

No obstante, dado que se trata de un cambio en el kernel, habrá que pasar toda la batería de tests antes de subir una nueva versión.

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

Status: newaccepted

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

(In [4109]) Refs #1428

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

Resolution: fixed
Status: acceptedclosed

(In [4112]) Fixes #1428

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

(In [4113]) VERSION_BUILD "b025"
Refs #1426
Refs #1428
Refs #1429

Note: See TracTickets for help on using tickets.