• Publicidad

Funcionamiento de map

Así que programas sin strict y las expresiones regulares son otro modo de hablar. Aquí encontrarás respuestas de nivel avanzado, no recomendable para los débiles de corazón.

Re: Funcionamiento de map

Notapor danimera » 2012-07-13 17:39 @777

explorer escribiste:Pero, ¿en qué momento hiciste el Dumper, y de qué?

Dices que el resultado del Dumper es correcto, pero ¿es justo después del receive()?

¿Y si haces un Dumper de $_->{ $usuario_nw } justo después de la asignación, para ver qué contiene?

Podría ser que siempre estés almacenando los valores en el mismo sitio...


Sí, el Dumper lo hice dentro del for, exactamente después del retrieve() y obtuve lo que envié anteriormente

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. for (@$contents) {
  2.  
  3.     my $creado_por = $_->{'created_by'};
  4.     my $usuario_rt = $usuario->retrieve( $creado_por );
  5.     die Dumper $usuario_rt;
  6.     my $usuario_nw = "creador_$creado_por";
  7.     $_->{ $usuario_nw } = $usuario_rt;
  8.  
  9. }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


y luego pues lo hice justo después de $_->{ $usuario_nw }

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. for (@$contents) {
  2.  
  3.     my $creado_por = $_->{'created_by'};
  4.     my $usuario_rt = $usuario->retrieve( $creado_por );
  5.    
  6.     my $usuario_nw = "creador_$creado_por";
  7.     $_->{ $usuario_nw } = $usuario_rt;
  8.     die Dumper $_->{ $usuario_nw };
  9. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


y obtengo


Sintáxis: [ Descargar ] [ Ocultar ]
  1. $VAR1 = bless( { 'primary_key' => 'user_id', 'fields' => [ 'user_id', 'username', 'password', 'email', 'creation_date', 'group_id', 'status' ], 'db_type' => 'CSV', 'belongs_to' => {}, 'table' => 'user', 'dbh' => bless( {}, 'DBI::db' ), 'data' => { 'email' => '[email protected]', 'password' => 'ahjjj', 'group_id' => '1', 'creation_date' => '2012-5-15', 'status' => '1', 'user_id' => '1', 'username' => 'admin' }, 'has_many' => { 'group' => { 'MyApp::Db::Group' => 'group_id' } } }, 'MyApp::Db::User' );  


Es decir, con esto que está bien, el retrieve() está funcionado bien :(
Definitivamente me doy, me doy, me doy...
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

Publicidad

Re: Funcionamiento de map

Notapor explorer » 2012-07-13 18:21 @806

Bueno, pues si el retrieve() está bien, y la asignación está bien, solo queda por pensar que el valor almacenado es modificado en la siguiente vuelta del bucle.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Funcionamiento de map

Notapor danimera » 2012-07-14 08:42 @404

Bueno, luego hice esto a ver qué pasaba ahí:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.      my @test;
  2.    for (@$contents) {
  3.  
  4.     my $creado_por = $_->{'created_by'};
  5.  
  6.     my $usuario_rt = $usuario->retrieve( $creado_por );
  7.  
  8.     my $usuario_nw = "creador_$creado_por";
  9.  
  10.     $_->{ $usuario_nw } = $usuario_rt;
  11.  
  12.     push(@test, $_->{ $usuario_nw });
  13.     #die Dumper  $_->{ $usuario_nw };
  14. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


El Dumper de @test me arroja:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. $VAR1 = bless( { 'primary_key' => 'user_id', 'fields' => [ 'user_id', 'username', 'password', 'email', 'creation_date', 'group_id', 'status' ], 'db_type' => 'CSV', 'belongs_to' => {}, 'table' => 'user', 'dbh' => bless( {}, 'DBI::db' ), 'data' => { 'email' => '[email protected]', 'password' => 'talary', 'group_id' => '2', 'creation_date' => '2012-6-14', 'status' => undef, 'user_id' => '3', 'username' => 'talary' }, 'has_many' => { 'group' => { 'MyApp::Db::Group' => 'group_id' } } }, 'MyApp::Db::User' ); $VAR2 = $VAR1; $VAR3 = $VAR1; $VAR4 = $VAR1; $VAR5 = $VAR1; $VAR6 = $VAR1; $VAR7 = $VAR1;  


pero si activo el die Dumper dentro del ciclo tengo:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. $VAR1 = bless( { 'primary_key' => 'user_id', 'fields' => [ 'user_id', 'username', 'password', 'email', 'creation_date', 'group_id', 'status' ], 'db_type' => 'CSV', 'belongs_to' => {}, 'table' => 'user', 'dbh' => bless( {}, 'DBI::db' ), 'data' => { 'email' => '[email protected]', 'password' => 'admin', 'group_id' => '1', 'creation_date' => '2012-5-15', 'status' => '1', 'user_id' => '1', 'username' => 'admin' }, 'has_many' => { 'group' => { 'MyApp::Db::Group' => 'group_id' } } }, 'MyApp::Db::User' );  


Ahora sí vemos una gran diferencia, en lo que pasa... :? Todos esos var que son igual a $VAR1 no entiendo por qué.
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

Re: Funcionamiento de map

Notapor explorer » 2012-07-14 09:02 @418

La línea

$VAR2 = $VAR1; $VAR3 = $VAR1; $VAR4 = $VAR1; $VAR5 = $VAR1; $VAR6 = $VAR1; $VAR7 = $VAR1;

indica que TODOS los elementos @test, son iguales entre sí.

Es una forma que tiene Dumper de ahorrar presentación.

También es cuando un elemento es una referencia a un elemento que ya ha sido impreso.

Interesante, entonces: es un bucle de 7 elementos, pero obtienes 7 elementos repetidos.

Algo, fuera del bucle, no está bien.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Funcionamiento de map

Notapor danimera » 2012-07-14 09:16 @427

Ya estoy algo más cerca...

Resulta que el último de los contenidos fue creado por el usuario con id = 3.
Hice esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     my @test;
  2.     for (@$contents) {
  3.         my $creado_por = $_->{'created_by'};
  4.         my $usuario_rt = $usuario->retrieve( $creado_por );
  5.         my $usuario_nw = "creador_$creado_por";
  6.         $_->{ $usuario_nw } = $usuario_rt;
  7.  
  8.         push(@test, $creado_por);
  9.         #die Dumper  $usuario_rt;
  10.         #
  11.     }
  12.     return Dumper  @test;
  13.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


y ahora el Dumper del test tiene:

Sintáxis: [ Descargar ] [ Ocultar ]
  1. $VAR1 = '1'; $VAR2 = '1'; $VAR3 = '1'; $VAR4 = '1'; $VAR5 = '1'; $VAR6 = '1'; $VAR7 = '3'; 


A lo que concluyo que el último valor me está afectado a todos los demás, ya que cuando quito el origen de ese $VAR7, ahora sí no tengo problemas con el código... Pero no tengo la solución de lo que puede estar pasando...

Creo que de alguna forma todos me apuntan con la misma referencia del último variable leído en el ciclo.
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

Re: Funcionamiento de map

Notapor explorer » 2012-07-14 13:24 @600

danimera escribiste:Creo que de alguna forma todos me apuntan con la misma referencia del último variable leído en el ciclo.

Entonces, en ese caso, retrieve() no devuelve un objeto, sino una referencia, y siempre es la misma.

Ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $ perl -MData::Dumper -E '%y = ( x1 => 1, x2 => 2); %x = ( a=>1, b=>\%y ); %z = ( t => \%y );  say Dumper \%x, \%y, \%z'
  2. $VAR1 = {
  3.           'a' => 1,
  4.           'b' => {
  5.                    'x2' => 2,
  6.                    'x1' => 1
  7.                  }
  8.         };
  9. $VAR2 = $VAR1->{'b'};
  10. $VAR3 = {
  11.           't' => $VAR1->{'b'}
  12.         };
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Las variables están definidas en un orden, y con Dumper las sacamos en otro. Dumper, al irlas sacando en pantalla, se da cuenta de que algunos valores salen repetidos, así que los muestra como $VARx.

En el Dumper que has sacado antes, se ha demostrado que lo que devuelve retrieve() es una referencia, y que siempre es la misma. Si modificas un valor dentro de esa referencia, cambia en todos los objetos a la vez.

Quizás la solución pase por crear un objeto nuevo con el contenido devuelto por retrieve(), y guardar en $_->{ $usuario_nw } la referencia a ese nuevo objeto.

Lo dicho... la solución pasa por ejecutar paso a paso, o empezar a recrear el bucle desde -casi- cero:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. print Dumper \@$contents;   # vemos el aspecto que tienen los elementos a procesar
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Luego damos un paso más allá:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. for my $i (0 .. $#$contents) {
  2.     print Dumper $contents->[$i];               # saca un elemento
  3.     exit;                                       # terminamos inmediatamente: solo nos interesa ver el primero
  4. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Aunque con el primer Dumper ya hemos sacado todos los valores, y ahora con el segundo código volvemos a sacar el primero, nos vamos asegurando que vamos manejando bien las referencias y las variables.

Y así vamos construyendo el bucle.

A veces hay que programar así, paso a paso, sobre todo cuando tenemos estructuras muy complejas o referencias por todas partes.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Funcionamiento de map

Notapor danimera » 2012-07-16 13:44 @614

MI función retrieve() es esta:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub retrieve {
  2.     my $self = shift;
  3.     my $id   = shift;
  4.  
  5.         return 0 unless $id;
  6.  
  7.  
  8.  
  9.     my $dbh = $self->{dbh};
  10.     my $table_name      = $self->{table};
  11.     my $fields          = $self->{fields};
  12.     my $pk              = $self->{primary_key};
  13.  
  14.  
  15.     my $query = "SELECT * FROM $table_name WHERE ($pk = $id)";
  16.  
  17.     #return $query;
  18.  
  19.      my $sth = $dbh->prepare($query) or die $dbh->errstr();
  20.  
  21.  
  22.     if ( $sth->execute() or die $dbh->errstr() ) {
  23.         $self->{data} = $sth->fetchrow_hashref();
  24.         return $self;
  25.     }
  26.     else {
  27.         return 0;
  28.     }
  29.  
  30. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Cómo sería la forma más óptima para que me retornara un objeto o un hash pero no una referencia? :S
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

Re: Funcionamiento de map

Notapor explorer » 2012-07-16 20:21 @890

Bueno, pues ya está aclarado el misterio.

En la línea

my $usuario_rt = $usuario->retrieve( $creado_por );

estás ejecutando retrieve() con dos argumentos: $usuario y $creado_por. $creador_por ya sabemos lo que contiene. Y $usuario es un objeto MyApp::Db::User.

Dentro de retrieve(), asignas $self a ese objeto. Se hace la consulta, y si no ocurre un error, guardas el resultado en {'data'} y luego devuelves $self. Eso quiere decir que

my $usuario_rt = $usuario->retrieve( $creado_por );

se convierte en

my $usuario_rt = $usuario;

Sí: $usuario_rt apunta al objeto apuntado por $usuario. Y como $usuario es una variable que viene fuera del bucle, eso quiere decir que $usuario_rt siempre apunta al mismo objeto, y que siempre

$_->{ $usuario_nw } = $usuario_rt;

guardará el mismo objeto en ese valor de hash. Por lo tanto, si modificas un valor en un elemento del array @$contents, lo cambias en todos. Mejor dicho: solo hay un elemento (un objeto MyApp::Db::User) referenciado por todos los elementos de @contents.

Por esa razón el Dumper sacaba todos los $VARx iguales entre sí.

El problema está en: a) $usuario viene de fuera del bucle y b) el resultado de retrieve() es $usuario, por lo que siempre estamos guardando/modificando el mismo objeto ($usuario).

Quizás... lo que quieres que haga retrieve() es que cree un objeto distinto por cada resultado de la consulta, y ese valor almacenarlo dentro de @$contents. O quizás, no es un objeto lo que esperas, sino que antes de llamar a retrieve, debes crear un nuevo $usuario, donde guardar la información del resultado de la consulta, y eso es lo que devuelve retrieve() (humm... creo que he dicho lo mismo :) ).

En cualquier caso, lo del return $self lo veo rarísimo. Seguro que es otra cosa lo que quieres devolver.

Si lo que quieres devolver es un hash, es muy sencillo:

return %{$sth->fetchrow_hashref()};

pero es más óptimo el devolver una referencia al hash:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $resultado_ref = $sth->fetchrow_hashref();         # referencia al resultado
  2. return $resultado_ref;                                # devolvemos la referencia
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

y luego, en el bucle, recoger la referencia y extraer de ella los valores del hash, o guardar directamente la referencia.

$_->{ $usuario_nw } = $usuario->retrieve( $creado_por );

Atención: no estamos guardando un objeto MyApp::Db::User, sino solo el resultado de la consulta.

Depende de la estructura de datos que quieras dejar en $contents.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Funcionamiento de map

Notapor danimera » 2012-07-23 15:44 @697

Hace rato que no respondía, y como que ¡no lo logro!

Por desgracia no lo pude lograr...

Sencillamente lo que quiero es devolver un objeto con todos sus datos dentro de la variable datos...
Ya comprendo el problema pero intenté esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub retrieve {
  2.     my $self = shift;
  3.     my $id   = shift;
  4.  
  5.         return 0 unless $id;
  6.  
  7.     my $dbh = $self->{dbh};
  8.     my $table_name      = $self->{table};
  9.     my $fields          = $self->{fields};
  10.     my $pk              = $self->{primary_key};
  11.  
  12.     my $query = "SELECT * FROM $table_name WHERE ($pk = $id)";
  13.     my $sth = $dbh->prepare($query) or die $dbh->errstr();
  14.  
  15.     if ( $sth->execute() or die $dbh->errstr() ) {
  16.         $self->{data} = %{$sth->fetchrow_hashref()};
  17.         return $self;
  18.     }
  19.     else {
  20.         return 0;
  21.     }
  22.  
  23. }
  24.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


y en el dumper tengo:

Sintáxis: [ Descargar ] [ Ocultar ]
  1. 'creador' => bless( { 'primary_key' => 'user_id', 'fields' => [ 'user_id', 'username', 'password', 'email', 'creation_date', 'group_id', 'status' ], 'db_type' => 'CSV', 'belongs_to' => {}, 'table' => 'user', 'dbh' => bless( {}, 'DBI::db' ), 'data' => '6/8',  


y si intento lo siguiente

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub retrieve {
  2.     my $self = shift;
  3.     my $id   = shift;
  4.  
  5.         return 0 unless $id;
  6.  
  7.     my $dbh = $self->{dbh};
  8.     my $table_name      = $self->{table};
  9.     my $fields          = $self->{fields};
  10.     my $pk              = $self->{primary_key};
  11.  
  12.     my $query = "SELECT * FROM $table_name WHERE ($pk = $id)";
  13.     my $sth = $dbh->prepare($query) or die $dbh->errstr();
  14.  
  15.     if ( $sth->execute() or die $dbh->errstr() ) {
  16.         my %resultado_ref = %{$sth->fetchrow_hashref()};        
  17.         $self->{data} = \%resultado_ref;
  18.            #$self->{data} = %{$sth->fetchrow_hashref()};
  19.         return $self;
  20.     }
  21.     else {
  22.         return 0;
  23.     }
  24.  
  25. }
  26.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


El problema persiste... El caso es que no puedo modificar mucho ese código porque ese mini ORM ya está corriendo en línea y así lo usan... así que no tengo otra alternativa que $self->{data} se guarde el valor y no que apunte a la misma referencia...

:( ¡¡¡Ay!!! Perl, ahora entiendo por qué dicen lo que dicen ti.
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

Re: Funcionamiento de map

Notapor explorer » 2012-07-23 16:27 @727

Sigues cometiendo el mismo fallo...

No puedo comentarte nada nuevo, porque no has hecho caso de lo que te he escrito.

Por favor, vuelve a leer mi anterior respuesta.

Resumen: el fallo está en el return $self, y en llamar a retrieve() con $usuario.

Primero, debes aclararte una cosa: estás llamando a retrieve() siempre con el mismo $usuario, así que siempre estás modificando el mismo $self->{data}.

Y lo que devuelves con return $self es el propio $usuario, así que estás guardando referencias a $usuario en todos los elementos de $contents.

No creo que sea eso lo que quieres hacer...

¿No tendrías que ir haciendo bucle por todos los usuarios? O quizás, solo quieras guardar el resultado de la consulta en cada elemento de $contents, y no en $usuario.

Entonces, te vale con (no probado)
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     my $hash_ref = $sth->fetchrow_hashref();
  2.     return $hash_ref;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


y luego
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     $_->{ $usuario_nw } = $usuario_rt;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

de esta manera, estás devolviendo el hash con el resultado en el retrieve(), y ese valor lo almacenas dentro de $contents, indexado bajo el valor de $usuario_nw.

Cada vez que llames a retrieve() se crea un nuevo espacio para la referencia al hash, así que no se sobreescriben.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

AnteriorSiguiente

Volver a Avanzado

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 21 invitados