2

My script download a plain text file using from the internet using LWP::Simple's get() function.

I'd the like to process this string in a filehandle way. I found this 'elegant' (well, I like it) way of doing this from http://www.perlmonks.org/?node_id=745018 .

my $filelike = get($url); # whole text file sucked up in single string
open my $fh, '<', \$filelike or die $!;
while (<$fh>) {
    # do wildly exciting stuff;
};

But I like using FileHandle; however, I've not found a way of doing the above using it. So:

my $filelike = get($url);
my $fh = new FileHandle \$filelike; # does not work
my $fh = new FileHandle $filelike; # does not work either

Any ideas?

Thanks.

moigescr
  • 87
  • 6

2 Answers2

0

FileHandle provides an fdopen method which can give you a FileHandle object from a symbol reference. You can open a raw filehandle to the scalar ref and then wrap that in a FileHandle object.

open my $string_fh, '<', \$filelike;
my $fh = FileHandle->new->fdopen( $string_fh, 'r' );

(Also, see this answer for why you should use Class->new instead of the indirect new Class notation.)

Community
  • 1
  • 1
friedo
  • 65,762
  • 16
  • 114
  • 184
  • 1
    Actually, playing around a bit more, I have got it to work. I used this from the FileHandle doc: "If FileHandle::open receives a Perl mode string (">", "+<", etc.) or a POSIX fopen() mode string ("w", "r+", etc.), it uses the basic Perl open operator." So `my $filelike = get($url); my $fh = new FileHandle \$filelike, 'r' or die $!;` works fine. Or, taking into account @friedo's advice (thanks for that): `my $fh = FileHandle->new(\$filelike, 'r') or die $!;` – moigescr Jul 23 '14 at 12:44
  • Hmmm.. The code friedo posted shouldn't work. The handle in `$string_fh` doesn't have an fd to open. – ikegami Jul 23 '14 at 18:38
  • Seems to work on 5.20 anyway: `perl -MFileHandle -E 'open my $string_fh, "<", \"some stuff"; my $fh = FileHandle->new->fdopen( $string_fh, "r" ); say $fh->getline'` – friedo Jul 23 '14 at 19:26
  • Yes, it *does* work, but it *shouldn't*. As a result, I don't trust it. Besides, creating two file handles is silly and unnecessary. – ikegami Jul 23 '14 at 19:29
0

Do you realize that all file handles are objects of the IO::Handle? If all you want is to use the file handle as an object, you don't have to do anything at all.

$ perl -e'
    open my $fh, "<", \"abcdef\n";
    STDOUT->print($fh->getline());
'
abcdef

Note: In older versions of Perl, you will need to add use IO::Handle;.

ikegami
  • 367,544
  • 15
  • 269
  • 518