2016-10-11 2 views
1

Am bekommen versuchen, ein Unterprogramm zu machen, die Daten je nach Datentyp ersetzt: das Problem ist, ich nicht den Datentyp des Parameters bekommen, habe ich dies:Perl Parameter Datentyp

sub replace { 
     my ($search, $replacement, $subject) = @_; 

     if (ref($search) eq "HASH") { 
      print "r is a reference to a HASH.\n"; 
     } 
     elsif (ref($search) eq "SCALAR") { 
      print "r is a reference to a SCALAR.\n"; 
     } 
     elsif (ref($search) eq "ARRAY") { 
      print "r is a reference to a ARRAY.\n"; 
     } 
    } 

my $str = "Foo"; 
my @arr = ("Foo"); 

replace($str); 
replace(@arr); 

Aber keiner arbeitet. bin wirklich neu in perl

Antwort

3

ref() braucht eine reference zu etwas, nicht das etwas an sich. Hier:

replace($str); 
replace(@arr); 

... Sie senden das etwas direkt. Senden Sie in einem Verweis auf die etwas stattdessen durch eine \ vor ihm setzen (die sagt: „nehmen Sie einen Hinweis auf diese etwas“):

replace(\$str); 
replace(\@arr); 

Ausgang:

r is a reference to a SCALAR. 
r is a reference to a ARRAY. 

Beachten Sie auch, dass in Ihrer replace() Funktion, in dieser Zeile:

my ($search, $replacement, $subject) = @_; 

Wenn Sie einen skalaren Wert als das, was effektiv zu fragen, zu suchen, so in einer Liste vorbei (Array, Hash usw.) wil l clobber $replacement und $subject, wenn die in der Liste übergeben mehr als ein Element hat, so dass Sie so etwas wie dies tun sollten, um sicherzustellen, werden Sie die richtigen params bekommen, und nichts ist unerwartet verprügelt:

sub replace { 
    my ($search, $replacement, $subject) = @_; 
    die "first arg must be a ref\n" if ! ref $search; 

Natürlich Sie können weitere Argumente überprüfen, aber dies stellt sicher, dass der erste Parameter nur ein Verweis auf etwas sein kann. Anstatt die() können Sie auch nur return, also stürzt das Programm nicht ab, oder print oder warn und dann return.

+0

Gibt es einen anderen Weg als das Hinzufügen? Wie kann ich es innerhalb der Subroutine tun? –

+0

@ChrysUgwu nein, da Funktionsparameter als eine große Liste zu perlieren scheinen. Sie können also keine Liste von Skalaren, Arrays oder Hashs unterscheiden, nachdem die Funktion sie bereits akzeptiert hat. – stevieb

1

Es ist nicht angegeben, was Sie damit machen wollen, aber hier ist was falsch ist mit dem, was Sie zeigen.

Die Funktion ref zeigt den Datentyp der Referenz, die an ihr submitted ist, oder sie gibt eine leere Zeichenfolge zurück, wenn ihr Argument überhaupt keine Referenz ist.

Also das erwartete Verhalten bekommen Sie auch

replace(\$str); 
replace(\@arr); 

tun sollten, müssen Sie den Test auf Ihre Funktion

else (not ref $search) 

für, wenn ein eingereichtes Zeichenfolge ist kein Verweis hinzuzufügen.


Der Vollständigkeit halber sollte ich auch ein Problem hinweisen, erklärte in der Antwort von stevieb. Wenn Sie ein Array an eine Funktion übergeben, erhält es eine flache Liste von Argumenten. Mit deiner Funktion willst du eindeutig nicht replace(@arr). Sie werden Ihrer Liste skalarer Variablen in der Reihenfolge, jeweils ein Element, zugewiesen. (Sobald es eine Array-Variable gibt, geht alles hinein.) Siehe zum Beispiel this post.

Verwandte Themen