Frage

In Perl ist es möglich, eine globale Variable zu erstellen, basierend auf einem String?

Z. B, wenn ich eine Funktion wie:.

sub create_glob_var {
    my ($glob_var_str) = @_;
    # something like this ( but not a hash access).
    our ${$glob_var_str};
};

und ich nannte es wie:

create_glob_var( "bar" );

Wie kann ich create_glob_var ändern, um tatsächlich eine globale Variable namens $bar erstellen?

Ihr Projekt wird mit Perl 5.8.5.

Bearbeiten

Die folgenden funktioniert nicht:

use strict;
BEGIN {
  sub create_glob_var {
    my ($glob_var_str) = @_;
    no strict 'refs';
    $$glob_var_str = undef;  # or whatever you want to set it to
  }

  create_glob_var("bah");
};

$bah = "blah";

Erzeugt:

Variable "$bah" is not imported at /nfs/pdx/home/rbroger1/tmp2.pl line 12.
Global symbol "$bah" requires explicit package name at /nfs/pdx/home/rbroger1/tmp2.pl line 12.
Execution of /nfs/pdx/home/rbroger1/tmp2.pl aborted due to compilation errors.

Hinweis Ich stelle fest, dass die globale Variablen verursacht Ozonabbau und männlich Kahlköpfigkeit . Ich versuche, einige Legacy-Code zu bereinigen, die bereits vollständig mit der Verwendung von globalen Variablen infiziert ist. Ein Refactoring zu einer Zeit ...

War es hilfreich?

Lösung

Wenn Sie versuchen, alten Code zu bereinigen, können Sie ein Modul schreiben, welches die gewünschte Variable (n) exportiert. Jedes Mal, wenn Sie die Notwendigkeit, invoke create_glob_var fühlen, sondern fügen Sie eine Variable zu diesem Paket und setzte sich in der Importliste.

Dies wird Ihnen helfen, zu verfolgen, was los ist und wie Variablen verwendet werden.

package MyVars;

use strict; use warnings;

use Exporter 'import';

our($x, %y, @z);

our @EXPORT_OK = qw( $x %y @z );

Das Skript:

#!/usr/bin/perl

use strict;use warnings;

use MyVars qw( $x %y @z );

$x = 'test';
%y = (a => 1, b => 2);
@z = qw( a b c);

use Data::Dumper;
print Dumper \($x, %y, @z);

Ausgabe:

$VAR1 = \'test';
$VAR2 = {
          'a' => 1,
          'b' => 2
        };
$VAR3 = [
          'a',
          'b',
          'c'
        ];

Andere Tipps

sub create_glob_var {
    my ($glob_var_str) = @_;
    no strict 'refs';
    $$glob_var_str = undef;  # or whatever you want to set it to
}

Die no strict 'refs' ist nur notwendig, wenn use strict in Kraft ist, was es immer sein sollte.

Nachtrag:

Wenn Sie sich fragen, ob es eine Möglichkeit gibt ein Unterprogramm create_glob_var, so dass der folgende Code zu schreiben, wird erfolgreich sein:

use strict;
create_glob_var("bar");
$bar = "whatever";

... dann ist die Antwort „Nein“ Perl vars Pragma wird jedoch tun, was Sie wollen:

use strict;
use vars qw($bar);
$bar = "whatever";

Aber das ist eine Art von altem Stil Perl-Codierung. Heute würde man dies in der Regel tun:

use strict;
our $bar = "blah";

our kann auch nur globale Variablen deklarieren, die frei später verwendet werden kann:

our ($foo, @bar, %baz);
# ...
$foo = 5;
@bar = (1, 2, 3);
%baz = (this => 'that');

Versuchen Sie, diese Frage suchen: Does Perl haben PHP-wie dynamische Variablen?

Kurz gesagt, scheint es, wie Sie in der Lage sein sollten, $$glob_var_str = "whatever"; zu tun

würden Sie haben eine eval verwenden, aber das ist in der Regel Übel angesehen. So etwas wie:

eval("$glob_var_str = \@_;");

EDIT

Just Nachweis erbracht, dass Sie dies nur tun, ohne die my und mit no strict refs.

Die vars Pragma bereits hat das schwere Heben für das, was Sie wollen, setzen Sie es so zu Arbeit:

#! /usr/bin/perl

use warnings;
use strict;
use vars;

BEGIN { vars->import(qw/ $bah /) }

$bah = "blah";
print $bah, "\n";

Wenn Sie buchstabieren bevorzugen es create_glob_var, dann verwenden Sie

#! /usr/bin/perl

use warnings;
use strict;
use vars;

sub create_glob_var { vars->import("\$$_[0]") }

BEGIN { create_glob_var "bah" }

$bah = "blah";
print $bah, "\n";

So oder so ist der Ausgang

blah

Ich bin neugierig zu wissen, warum Sie es auf diese Weise tun wollen, anstatt diese Variablen mit our . Ja, kann es ein paar Iterationen, um sie alle zu fangen, aber diese sind ohnehin kurzfristige Korrekturen, nicht wahr?

Im Allgemeinen Sie eine Variable als Variablennamen verwenden (siehe "symbolische Referenzen "in perlref ), aber Sie wirklich, wirklich, wirklich wollen nicht, das zu tun. ermöglicht die strict 'refs' Pragma deaktiviert diese Funktion

Rafael Garcia-Suarez zeigte große Weisheit, als er schrieb: „Ich weiß nicht, was Ihr ursprüngliches Problem ist, aber ich schlage vor, einen Hash zu verwenden.“

Siehe auch:

Antwort von Sinan Unur ist in der Tat die beste. Doch diese meine Neugier gepflückt, so dass ich ein bisschen zu lesen (perldoc perlmod) und lernte über „package_name ::“ Hash als eine Möglichkeit, den Namensraum eines Pakets zuzugreifen hat.

Der folgende Code fügt einen Datensatz zu Symboltabelle der Haupt :: Paket:

use strict;
my $name = "blah";
my $var = "sss";
$main::{$name} = \$var;

print "$main::blah\n";

Diese Drucke "sss".

Allerdings hatte ich Paketnamen print-Anweisung hinzugefügt werden, da „use strict“ ist noch nicht täuschen. Ich werde weiter suchen -. Verwendung vars zur Zeit nicht zur Arbeit scheint

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top