Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I can create filehandles to strings in Perl 5, how do I do it in Perl 6?

In Perl 5, I can create a filehandle to a string and read or write from the string as if it were a file. This is great for working with tests or templates.

For example:

use v5.10; use strict; use warnings;

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

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

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

How can I do that in Perl 6? The following doesn't work for Perl 6 (at least not for my instance of Perl6 running on MoarVM 2015.01 from the January 2015 release of Rakudo Star on 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

I get the error message:

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

It's not very surprising that Perl5's open(my $fh, '<', \$text) is not the same as Perl6's my $fh = $text;. So the question is: How does one create a virtual file handle from a string in Perl 6 like open(my $fh, '<', \$str) in Perl 5? Or is that something that has yet to be implemented?

UPDATE (writing to a filehandle in Perl 5)

Likewise, you can write to string filehandles in Perl 5:

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";

Outputs:

 My string is 'ABC'

I haven't seen anything remotely similar in Perl 6, yet.

like image 224
Christopher Bottoms Avatar asked Feb 24 '15 17:02

Christopher Bottoms


People also ask

How do I use FileHandle in Perl?

The three basic FileHandles in Perl are STDIN, STDOUT, and STDERR, which represent Standard Input, Standard Output, and Standard Error devices respectively. File Handling is usually done through the open function. Syntax: open(FileHandle, Mode, FileName);

What is FH in Perl?

File handling is the most important part in any programming language. A filehandle is an internal Perl structure that associates with a file name. Perl File handling is important as it is helpful in accessing file such as text files, log files or configuration files.

How do I open a reading and writing file in Perl?

If you want to open a file for reading and writing, you can put a plus sign before the > or < characters. open DATA, "+>file. txt" or die "Couldn't open file file.


1 Answers

Reading

The idiomatic way to read line-by-line is the .lines method, which is available on both Str and IO::Handle.

It returns a lazy list which you can pass on to for, as in

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

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

Writing

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

(Adapted from #perl6, thanks to Carl Mäsak.)

More advanced cases

If you need a more sophisticated mechanism to fake file handles, there's IO::Capture::Simple and IO::String in the ecosystem.

For example:

use IO::Capture::Simple;
my $result;
capture_stdout_on($result);
say "Howdy there!";
say "Hai!";
capture_stdout_off();
say "Captured string:\n" ~$result;
like image 137
Christoph Avatar answered Oct 21 '22 19:10

Christoph