2008-11-12 8 views
11

En PHP, puedo escribir:¿Perl tiene variables dinámicas similares a PHP?

$vname = 'phone'; 
$$vname = '555-1234'; 
print $phone; 

... Y el guión te mostrará "555-1234".

¿Hay algún equivalente en Perl?

¿Hay alguna forma de restringir $phone al alcance del bloque local, como si hubiera escrito my $phone? El uso de my $$vname me da errores "No puedo declarar la desreferencia escalar en mi en ...".

+0

Pongo esto en la respuesta de la CMS, ya que no vi esta edición, pero debe ser "$$ vname = '555 -1234 '", elimina el" mi ". – gpojd

+2

Este es código obsoleto incluso en PHP. Como otros han publicado, use un hash. – staticsan

+2

Esa característica se copió de Perl, cuando PHP se escribió en Perl. –

Respuesta

56

Lo que está intentando hacer se denomina "referencia simbólica". Mientras puede hacer esto en Perl you shouldn't. Las referencias simbólicas solo funcionan con variables globales, no léxicas (my). No hay forma de restringir su alcance. Las referencias simbólicas son peligrosas. Por esa razón, no funcionan en el pragma strict.

En general, cada vez que usted piensa que necesita referencias simbólicas que debe utilizar un hash lugar:

my %hash; 
$hash{phone} = '555-1234'; 
print $hash{phone}; 

Hay algunos casos en los symrefs son útiles e incluso necesario. Por ejemplo, el mecanismo de exportación de Perl los usa. Estos son temas avanzados. Para cuando esté listo para ellos, no tendrá que preguntar cómo. ;-)

8

Puede hacerlo de una manera muy similar:

Pero eso puede no significa que usted debe. La mejor forma de administrar esto es as Michael Carman says, ¡USE UN DISCO DURO!

+1

¿Por qué nunca supe que podrías hacer eso en Perl? –

+0

Ta. ¿Hay alguna forma de restringir $ phone al alcance del bloque local, como si hubiera escrito "my $ phone"? El uso de "my $$ vname" me da los errores "No puedo declarar la desreferencia escalar en mi en ...". –

+0

Esto me da el siguiente error: "Símbolo global" $ teléfono "requiere nombre explícito del paquete en la línea 6. de temp.pl". – Svante

6

No se puede hacer esto con el pragma estricto habilitado, y el estricto pragma siempre debe estar habilitado. Puede hacerlo con el pragma fuera sin embargo, echar un vistazo a este un trazador de líneas:

perl -le 'my $vname = "phone"; ${ $vname } = "555-1234"; print $phone' 

Eso funcionará, pero esto no será:

perl -Mstrict -le 'my $vname = "phone"; ${ $vname } = "555-1234"; print $phone' 

"-Mstrict" le dice que "el uso estricto".

Casi siempre es mejor usar un hash para algo como esto, que es casi lo mismo que una matriz asociativa en PHP.

13

Lea las afirmaciones de Mark-Jason Dominus en contra de hacer esto en Why it's stupid to `use a variable as a variable name'.

Se podría limitar el alcance de los cambios en $ teléfono iniciando el bloque con

local $phone; 

o incluso

local $$vname; 

(Aunque tampoco cambios $ teléfono para cualquier submarinos llamado desde su bloque demasiado , entonces no es lo mismo que el alcance léxico de una declaración my().)

+3

Nunca contemplé el uso de C para limitar el alcance de un symref. Eso es a la vez interesante y perverso. Es como decir que estás dispuesto a pegarse un tiro en el pie, pero solo con una pistola BB. –

0

¿Te das cuenta de que PHP hereda muchas de sus características de Perl, ¿verdad?

No sólo puede Perl hacer todo lo simbólico PHP material de referencia puede,

use strict; 
use warnings; 
use 5.010; 

our $test=1; 

# Access $test through the special hash %:: 
say ${$::{test}}++; 

# This is essentially what the previous line did. 
say ${\$test}++ 

# Same as $test 
say ${test}++; 

{ 
    # PHP's simple symbolic ref 
    my $ref = "test"; 
    no strict 'refs'; 
    say $$ref++; 
    say ${"test"}++; 
} 
{ 
    package d; 
    say ${$main::{test}}++; 

    my $ref = $main::{"test"}; 
    say $$ref++; 

    $ref = \$main::test; 
    say $$ref++; 
}