Foros del Web » Programación para mayores de 30 ;) » Programación General »

Variable scope con local

Estas en el tema de Variable scope con local en el foro de Programación General en Foros del Web. Hola, Estoy intentando entender el uso de local para el scope de variables. Ejemplo tomado de una web: Código: use warnings; $lo = 'global'; $m ...
  #1 (permalink)  
Antiguo 10/04/2007, 10:49
 
Fecha de Ingreso: enero-2007
Mensajes: 22
Antigüedad: 17 años, 3 meses
Puntos: 0
Variable scope con local

Hola,

Estoy intentando entender el uso de local para el scope de variables.
Ejemplo tomado de una web:

Código:
    
         use warnings;
        $lo = 'global';
        $m  = 'global';
        A();
        sub A {
          local $lo = 'AAA';
          my    $m  = 'AAA';
          B();
        }
        sub B {
          print "B ", ($lo eq 'AAA' ? 'can' : 'cannot') ,
                " see the value of lo set by A.\n";
         print "B ", ($m  eq 'AAA' ? 'can' : 'cannot') ,
                " see the value of m  set by A.\n";
        }
Esto imprime:
Cita:
B can see the value of lo set by A.
B cannot see the value of m set by A.
Con este ejemplo se ve claramente como funciona local. Pero siempre trabajo con use strict; por lo tanto me pedira que declare las variables.
Si declaro con my las dos primeras variables consigo el siguiente error:
Cita:
Can't localize lexical variable $lo
No se puede utilizar local con strict?

Queria utilizar esta funcion por que me encuentro que en mi programa necesitaria utilizar unas variables de una subrutina en otra subrutina utilizada en la primera subrutina sin pasar las variables a la segunda. ( TOMA! me he explicado bien?)

Muchas gracias por vuestra ayuda,

Flope
  #2 (permalink)  
Antiguo 10/04/2007, 12:29
Colaborador
 
Fecha de Ingreso: mayo-2006
Ubicación: Valladolid
Mensajes: 524
Antigüedad: 18 años
Puntos: 11
Re: Variable scope con local

Declara las variables globales con our:

our $lo = 'AAA';
  #3 (permalink)  
Antiguo 10/04/2007, 15:14
 
Fecha de Ingreso: enero-2007
Mensajes: 22
Antigüedad: 17 años, 3 meses
Puntos: 0
Re: Variable scope con local

Muchas gracias.
Si, eso soluciona el problema anterior.
Pero esta aproximacion, creo que no me sirve para mi programa. Tengo que obtener las areas de una funcion para diferentes sets de datos. El problema es que la funcion no es sencilla (incluye sumatorio).

Para calcular la integral utilizo un modulo de CPAN q calcula el area de f(x) para un valor maximo y minimo. Este modulo necesita una referencia a una funcion f.

Para un solo set de datos (@datos) valdria lo siguiente ya que puedo utilizar @datos y $nos_datos como variables globales.

Código:
$nos_datos =  scalar @datos;

          use Math::Integral::Romberg 'integral';
	  my $area = integral(\&f, $imin, $imax); 

sub f {
     my ($x) = @_;
     my $output = 0;
     for my $dato (@datos) {
		 $output += (20 * $dato * $x * $x * exp(-16 * $dato * $x ));
     }
     return ($output/$nos_datos);
}
Pero cuando tengo que repetir este calculo del area para diferentes sets de datos (diferentes @datos) ya no puedo utulizar estas variables como globales. Estas se quedan como locales cuando hago el loop para recorrer los diferentes sets de datos.

sugerencias? Pasar de la funcion Romberg i crear mi propia subroutina? Canviar la estructura del programa?

Lo siento si no me he explicado bien.

Muchas gracias por vuestra ayuda y tiempo!!!
  #4 (permalink)  
Antiguo 10/04/2007, 18:18
Colaborador
 
Fecha de Ingreso: mayo-2006
Ubicación: Valladolid
Mensajes: 524
Antigüedad: 18 años
Puntos: 11
Re: Variable scope con local

Bueno, si necesitas calcular varias $areas correspondientes a varios conjuntos de @datos, entonces puedes hacer un bucle y cada $area la metes (push) en un array de @areas.

Además, el significado de 'global' se refiere al ámbito de actuación de una variable. No significa que su contenido sea una constante. Es la lógica de nuestro programa la que determinará si lo usamos de constante o no.

Si quieres dejar la información de @datos y $nos_datos de forma constante para cada conjunto de datos, usa OTRAS variables para almacenar los datos de cada ciclo y pásalas como argumentos a la función (o no se las pases y usa OTRAS variables globales para que la función sepa qué datos tiene que procesar).
  #5 (permalink)  
Antiguo 10/04/2007, 18:45
 
Fecha de Ingreso: enero-2007
Mensajes: 22
Antigüedad: 17 años, 3 meses
Puntos: 0
Re: Variable scope con local

Lo siento seguramente no me he explicado nada bien.

Cita:
Bueno, si necesitas calcular varias $areas correspondientes a varios conjuntos de @datos, entonces puedes hacer un bucle y cada $area la metes (push) en un array de @areas.
Si ningun problema con eso y como almacenar mis resultados. El problema es que no obtengo ningun resultado de area aun.
Cita:
Además, el significado de 'global' se refiere al ámbito de actuación de una variable. No significa que su contenido sea una constante. Es la lógica de nuestro programa la que determinará si lo usamos de constante o no.
Si tambien entiendo esto. Cuando digo global me refiero al ambito de actuacion (scope) de la variable.
El problema es que no puedo pasar (o no se como) las variables que no son $x a la funcion.
Intentare explicarme. Uso el siguiente codigo para calcular la integral. Enviando una referencia de una funcion (la subrutina de mi segundo mensaje), el max i el min para inegrar.
Código:
          use Math::Integral::Romberg 'integral';
	  my $area = integral(\&f, $imin, $imax);
Este modulo pasara SOLO diferentes valores de $x, creo, a la funcion (subrutina f) para calcular el area.
Como puedo pasar el resto de variables a mi funcion? Sin enviarlos al modulo Romberg?
Cuando solo tenia un set de datos era facil por que el ambito de @datos y $nos_datos llegaba hasta la subroutina.
Con mas de un set de datos tengo metido en un bucle esto:
for my @datos (@set_datos) { #me he inventado la linea
Código:
          use Math::Integral::Romberg 'integral';
	  my $area = integral(\&f, $imin, $imax);
}
Esto hace que mis variables como @datos esten solo definidas dentro de este bucle. Puedo poner el codigo anterior en otra subrutina pero luego solo estaran definidas en esa misma (de aqui el primer mensaje sobre "local" pero no funciona).
He provado varias cosas para intentar que estas variables estubieran definidas dentro de la subrutina f sin tener que pasarlas pero nada.
Alguna idea?
Esto es solo un calculo entre otros que hago con estos datos.

Muchas gracias!

Última edición por flope; 10/04/2007 a las 19:07
  #6 (permalink)  
Antiguo 11/04/2007, 02:17
Colaborador
 
Fecha de Ingreso: mayo-2006
Ubicación: Valladolid
Mensajes: 524
Antigüedad: 18 años
Puntos: 11
Re: Variable scope con local

Puedes entonces lo que necesitas es cambiar los contenidos de @datos antes de llamar a integral(). Si no puedes pasar variables a f(), entonces la opción es usar variables globales. Pues entonces debes cambiarlas antes de llamar a integral().

La línea inventada que tienes sólo te servirá si @set_datos es un array de arrays de datos, pero quedará mucho mejor si lo haces con referencias:

A la hora de construir la estructura de datos:
Código:
our $datos_ref;
our @set_datos;
# bucle para inicializar los datos
# ...
    push @set_datos, [@datos];
# ...
Luego, en el bucle principal
Código:
for $datos_ref ( @set_datos ) {
    integral();
}
y dentro de integral();
Código:
    for my $dato ( @$datos_ref ) {
         ...
    }
  #7 (permalink)  
Antiguo 11/04/2007, 02:23
Colaborador
 
Fecha de Ingreso: mayo-2006
Ubicación: Valladolid
Mensajes: 524
Antigüedad: 18 años
Puntos: 11
Re: Variable scope con local

He vuelto a leer el problema, y parece que lo único que te falla es la visibilidad de las variables dentro de f(). Ese es un problema distinto al de la forma de almacenar los datos. Y con mi primera respuesta dijiste que sí te lo solucionaba...
  #8 (permalink)  
Antiguo 11/04/2007, 08:00
 
Fecha de Ingreso: enero-2007
Mensajes: 22
Antigüedad: 17 años, 3 meses
Puntos: 0
Re: Variable scope con local

Cita:
He vuelto a leer el problema, y parece que lo único que te falla es la visibilidad de las variables dentro de f(). Ese es un problema distinto al de la forma de almacenar los datos. Y con mi primera respuesta dijiste que sí te lo solucionaba...
Hay dias que me sorprendo a mi mismo solucionando problemas complejos elegantemente con unas pocas linias de perl o de diferentes maneras haciendo cada dia los programas mas leibles..,....
pero, joder, ayer debia estar espeso de cojones! Hoy, me he puesto, y en 30 segundos ya estaba solucionado.
Si el problema era sobre visibilidad de las variables. La verdad es que tampoco me he explicado muy bien en los otros mensajes.
Solo he tenido que definir/inicializar las variables (my @datos y my $nos_datos) fuera del bucle "for my @datos (@set_datos) {....}" y ya ta.
La forma de definir el bucle ahora ha cambiado. Dentro de el solo tengo que asignar los nuevos valores.
Supongo que no queria cambiar el bucle e insistia en solucionar el problema con cosas como "local" y otras.....Espeso, espeso!
PERDON! La proxima vez intentare poner algun problema mas interesante para resolver.
Muchas gracias jferrero!!!
Estas en Valladolid?
Entonces te fuiste a dormir tarde ayer!

Última edición por flope; 11/04/2007 a las 08:07
  #9 (permalink)  
Antiguo 11/04/2007, 17:20
Colaborador
 
Fecha de Ingreso: mayo-2006
Ubicación: Valladolid
Mensajes: 524
Antigüedad: 18 años
Puntos: 11
Re: Variable scope con local

Ahora estoy en Madrid, pero sí, me cuesta mucho dormirme.

Pertenezco a ese 20% de la población que tenemos horarios biológicos extremos: matutinos y vespertinos. A mi me ha tocado ser vespertino.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 12:30.