6

In Perl 5, I can open a filehandle on string like this:

open my $kfh, "<", \$message->payload;

I have a scenario that uses string as a filehandle and passes it to the open method:

my $fh = new IO::Zlib;
open my $kfh, "<", \$message->payload;
if($fh->open($kfh, 'rb')){
   print <$fh>;
   $fh->close;
}

where $message->payload is read from Kafka, and the content is a byte array. raiph had a similar question, but it didn't answer my question.

So I want to know how to open a filehandle on a string in Perl 6 like Perl 5 does? These documentation pages have no information on this:

Tyil
  • 1,797
  • 9
  • 14
chenyf
  • 5,048
  • 1
  • 12
  • 35
  • [The documentation](https://docs.perl6.org/language/io) has a section about this under Input/Output. – callyalater Jul 18 '18 at 17:22
  • @callyalater I'm afraid not. the document only mentioned open a file, instead of open a filehandle on a string. – chenyf Jul 18 '18 at 17:33
  • The documentation also refers to the `IO::Handle` class. So, you can just stop at the `$filename.IO` to get the `IO` role object or you can do `$filename.IO.open` and get the `IO::Handle` filehandle object for the string. – callyalater Jul 18 '18 at 17:36
  • 3
    Possible duplicate of [I can create filehandles to strings in Perl 5, how do I do it in Perl 6?](https://stackoverflow.com/questions/28702850/i-can-create-filehandles-to-strings-in-perl-5-how-do-i-do-it-in-perl-6) – raiph Jul 18 '18 at 17:49
  • 1
    @callyalater That's a convenient way to turn a string containing a *filename* into a handle to that *file*. I can totally see why you're thinking that that's "open a filehandle on a string". But language is ambiguous and it looks like OP is asking about a scenario where no file is involved at all but rather to pretend there's a file *containing* a string, and to open that pretend file. See the SO I just linked. – raiph Jul 18 '18 at 17:56
  • @raiph I see what you are saying now. Yeah, what you linked to is much better. Thank you for the clarification. – callyalater Jul 18 '18 at 17:58
  • 1
    zef install [IO::String](http://modules.perl6.org/dist/IO::String) – Brad Gilbert Jul 19 '18 at 01:12

1 Answers1

4

EDIT: See this question for how to do what @raiph says about opening a filehandle to a string. Also, read @raiph's comments.

This is how to open a filehandle to a file from a string, not how to open a filehandle to a string without a file being involved. Thanks to @raiph for clarifying the OP's meaning.


The documentation has a section called Input/Output that describes this process.

One way to read the contents of a file is to open the file via the open function with the :r (read) file mode option and slurp in the contents:

my $fh = open "testfile", :r;
my $contents = $fh.slurp-rest;
$fh.close;

Here we explicitly close the filehandle using the close method on the IO::Handle object. This is a very traditional way of reading the contents of a file. However, the same can be done more easily and clearly like so:

my $contents = "testfile".IO.slurp;
# or in procedural form: 
$contents = slurp "testfile"

By adding the IO role to the file name string, we are effectively able to refer to the string as the file object itself and thus slurp in its contents directly. Note that the slurp takes care of opening and closing the file for you.

This is also found in the Perl5 to Perl6 pages as well.

In Perl 5, a common idiom for reading the lines of a text file goes something like this:

open my $fh, "<", "file" or die "$!";
my @lines = <$fh>;                # lines are NOT chomped 
close $fh;`

In Perl 6, this has been simplified to

my @lines = "file".IO.lines; # auto-chomped

Further references to do this are found in the IO::Handle documentation:

Instances of IO::Handle encapsulate an handle to manipulate input/output resources. Usually there is no need to create directly an IO::Handle instance, since it will be done by other roles and methods. For instance, an IO::Path object provides an open method that returns an IO::Handle:

my $fh = '/tmp/log.txt'.IO.open;
say $fh.^name; # OUTPUT: IO::Handle 
callyalater
  • 3,102
  • 8
  • 20
  • 27