2012-03-31 8 views
1

Ich möchte einen Wrapper um printf(...) programmieren.Verwenden Sie variadic Argumente als Argumente für sprintf

Mein erster Versuch war:

sub printf2 { 
    my $test = sprintf(@_); 
    print $test; 
} 

Als Array (in Skalarkontext) ist kein Formatstring, das funktioniert nicht (wie erwartet).

Kennt jemand eine Lösung? Wahrscheinlich ohne spezielle Pakete zu benutzen?

EDIT: Im realen Kontext möchte ich sprintf verwenden. Offensichtlich gibt es einen Unterschied zwischen printf und sprintf.

+1

Was genau Sie die Wrapper tun wollen? – choroba

+0

Die Hülle fungiert als eine Logger-Funktion, die z.B. Fügt jeder Ausgabezeile die aktuelle Zeit hinzu. – SecStone

Antwort

2

Wie über diese

sub pf { printf $_[0],@_[1..$#_] } 
+3

Das macht nur das Richtige für genau drei Argumente. Ich denke du meinst 'printf $ _ [0], @_ [1 .. $ # _]' – hobbs

7

Die sprintf Funktion hat ein ([email protected])prototype, so dass das erste Argument sprintf wird immer im skalare Kontext ausgewertet, auch wenn es ein Array ist.

$x = sprintf(@a);  # same as sprintf(scalar @a) 

Also, bevor Sie sprintf aufrufen, müssen Sie die Vorlage aus dem Rest der Argumente trennen. Hier ist eine kurze Art und Weise:

sub printf2 { 
    my $test = sprintf(shift, @_); 
    print $test; 
} 

Merkwürdiger, printf kein Prototyp hat und tut, was Sie erwarten.

printf(@a);   # same as printf($a[0], @a[1..$#a]) 
0

Viele der named operators (wie sprintf) haben spezielle Syntax. sprintf ‚s Syntax ist definiert als

sprintf FORMAT, LIST 

Dies kann oft (aber nicht immer) mit prototype zu sehen.

Das Problem ist, dass Sie eine der folgenden Syntax anstelle der dokumentierten Syntax verwendet haben.

Wechseln Sie einfach zur dokumentierten Syntax, um Ihr Problem zu lösen.

sub printf2 { 
    my ($format, @args) = @_; 
    print sprintf($format, @args); 
} 

Oder wenn Sie das Kopieren vermeiden wollen,

sub printf2 { 
    print sprintf($_[0], @_[ 1..$#_ ]); 
} 
Verwandte Themen