2015-02-24 19 views
8

In Perl 5 kann ich ein Dateihandle zu einer Zeichenfolge erstellen und aus der Zeichenfolge lesen oder schreiben, als ob es eine Datei wäre. Dies ist ideal für die Arbeit mit Tests oder Vorlagen.Ich kann Dateihandles zu Strings in Perl 5 erstellen, wie mache ich das in Perl 6?

Zum Beispiel:

use v5.10; use strict; use warnings; 

my $text = "A\nB\nC\n"; 

open(my $fh, '<', \$text); 

while(my $line = readline($fh)){ 
    print $line; 
} 

Wie kann ich das in Perl 6? Die folgenden nicht Arbeit für Perl 6 (zumindest nicht für meine Instanz Perl6 läuft auf MoarVM 2015.01 vom January 2015 release of Rakudo Star auf 64-Bit CentOS 6.5):

# Warning: This code does not work 
use v6; 

my $text = "A\nB\nC\n"; 

my $fh = $text; 

while (my $line = $fh.get) { 
    $line.say; 
} 
# Warning: Example of nonfunctional code 

ich die Fehlermeldung:

No such method 'get' for invocant of type 'Str' 
    in block <unit> at string_fh.p6:8 

Es ist nicht sehr überraschend, dass Perl5 der open(my $fh, '<', \$text)my $fh = $text; nicht das gleiche wie Perl6 der ist. Die Frage ist also: Wie erstellt man ein virtuelles Datei-Handle aus einer Zeichenkette in Perl 6 wie open(my $fh, '<', \$str) in Perl 5? Oder ist das etwas, das noch umgesetzt werden muss?

UPDATE (Schreiben auf eine Dateihandle in Perl 5)

Ebenso Sie String Dateihandies in Perl 5 schreiben:

use v5.10; use strict; use warnings; 

my $text = ""; 
open(my $fh, '>', \$text); 

print $fh "A"; 
print $fh "B"; 
print $fh "C"; 

print "My string is '$text'\n"; 

Ausgänge:

My string is 'ABC' 

Ich habe nicht in Perl 6 noch etwas Ähnliches gesehen.

+1

Btw. Der 'while (my $ line ...) {...}' -Code lexikalisch nicht '$ line', wie Sie denken. Die "$ -Zeile" endet lexikalisch im umgebenden Kontext, dem Hauptteil des Skripts. Es ist nicht auf die folgenden Klammern beschränkt. Stattdessen werden lexikalische Variablendeklarationen, die 'my' verwenden, auf ihre umschließenden geschweiften Klammern beschränkt. Parameter im Gegensatz * sind * auf die folgenden Klammern beschränkt, da dies der Codeblock ist, der auf die Parameter wirkt.Die '$ -Zeile 'im' -> $ -Zeilencode in der ersten (einzigen) Antwort unten ist ein Parameter. – raiph

+0

In P5 ist '$ line' eine nicht deklarierte Variable außerhalb der while-Anweisung (' use strict; use warnings; 'wird dies zeigen), während in P6 diese bekannt wäre. – raiph

+0

@raip Oh, okay. Jetzt sehe ich, dass Ihr erster Kommentar sich vollständig auf Perl 6 bezieht. Ich habe gerade eine 'while (meine $ line = ...' Schleife in Perl 6 versucht und Sie haben Recht, dass '$ line' außerhalb der Schleife liegt. Allerdings Es hat keinen Wert außerhalb der Schleife. Nach der Schleife gibt '$ line.say' '(Any)' aus, was bedeutet, dass es im Umfang liegt, aber im Grunde undefiniert ist. –

Antwort

8

Lesen

Die idiomatische Weg line-by-line zu lesen ist die .lines method, die sowohl auf Str verfügbar ist und IO::Handle.

Es gibt eine faule Liste, die Sie

my $scalar; 
my $fh = IO::Handle.new but 
     role { 
      method print (*@stuff) { $scalar ~= @stuff }; 
      method print-nl  { $scalar ~= "\n" } 
     }; 

$fh.say("OH HAI"); 
$fh.say("bai bai"); 

say $scalar 
# OH HAI 
# bai bai 

auf for, wie in

my $text = "A\nB\nC\n"; 

for $text.lines -> $line { 
    # do something with $line 
} 

Schreiben (Angepasst von #perl6 dank Carl Mäsak.)

Mehr passieren kann erweiterte Fälle

Wenn Sie eine mehr benötigen phistizierter Mechanismus, um Dateigriffe zu fälschen, gibt es IO::Capture::Simple und IO::String in der ecosystem.

Zum Beispiel:

use IO::Capture::Simple; 
my $result; 
capture_stdout_on($result); 
say "Howdy there!"; 
say "Hai!"; 
capture_stdout_off(); 
say "Captured string:\n" ~$result; 
+0

Ich mag den pädagogischen Wert der Verwendung des expliziten' -> $ foo'-Bits, aber in der Praxis wird die 'for ...' -Anweisung oft für 'text.lines {.foo } 'wo die' .foo' Methode für "it" aufgerufen wird. ("It" ist die Variable '$ _', die sowieso automatisch zugewiesen wird, wenn man" topicizers "wie' for' schreibt.) – raiph

+1

@raiph Es ist eine Frage der Präferenz. Früher habe ich in Perl 5 oft '$ _' verwendet, bevorzuge jetzt aber explizitere Variablen. Es mag ein bisschen mehr wortreich sein, aber ich bin auf Wartungsfreundlichkeit und Prägnanz bedacht. Ich bin froh, dass Perl 6 auch TIMTOWTDI ist. –