OI::M::Finally({IO::All})

Get it?

(Meant to post this to perlmonks, but the site's submission form is missing the [Add] button right now).

Anyway, as a long time user of File::Slurp who utilizes both idioms below often:

# slurp into a scalar
$content = slurp("file.txt");

# slurp into an array
@lines = slurp("file.txt");

I'm willing to switch to IO::All's:

# slurp into a scalar
io("file.txt") > $content;

But there's no array counterpart:

# slurp into an array
io("file.txt") > @lines;

I've hopelessly tried several variants:

io("file.txt") > \@lines;
io("file.txt") >> @lines;
io("file.txt") >> \@lines;
@lines = @{ io("file.txt") };
@lines = <io("file.txt")>;

None of them works. Do I really have to settle with:

@lines = io("file.txt")->slurp;

But where's the coolness of using IO::All in this case?

I'm loving the other features of IO::All though, like append, tie, copy, path, dir, etc. Yes, it's totally mad.

8 Comments

Hmm, this should work

@lines = @{ io("file.txt") };

Since in IO::All::File, @{} is overloaded to deref it as Tie::File

Tested with IO::All 0.46

It doesn't look like operator overloading will yield array output, but instead of slurp, all will be a bit nicer. :)

Apropos:

let you run code in the middle of a pipeline of commands. This is the killer feature for fully participating in pipelines, instead of just running them (as Perl and Python do).
(For bonus points, the code should be able to change the global state of the program instead of just running in a sub-process.)

Letting subroutines participate in pipelines, perhaps by overloading the '|' operator, would be really useful. I briefly played around with something like this several years ago, but didn't end up with anything I liked.

Its not really the same thing, but you might want to look at Zoidberg (why not Zoidberg?).

Good to see that Zoidberg's alive again. My zsh muscle memory was a bit too strong the last time I tried it, but it was a really nice merger of Perl and Unix the shell.

That said, I was thinking of something that worked within Perl's syntax, e.g.

io("file.txt") | sub { ... } | io("| frob > file2.txt");

But "|"'s precedence is a pain, there's the question of line-at-a-time vs. whole-output, etc.

This seems to suggest that it's theoretically doable:

perl -e'use overload ">" => sub { use Data::Dumper; print Dumper \@_ }; my @a; my $o = bless []; $o > \@a'

The overload sub clearly gets passed an arrayref; the arrayref doesn't get numified first or anything annoying like that.

Someone just needs to make a few adjustments to the following IO::All methods to detect when the scalar is an arrayref and DWIM.

  • overload_any_to_scalar
  • overload_any_addto_scalar
  • overload_scalar_addto_any
  • overload_scalar_to_any

It was never very broken. There was a test failure that got introduced by some esoteric change between 5.8 and 5.10. I fixed that, one other rare bug and simplified the build process. Jaap gave me co-maint and there you go!

Leave a comment

About Steven Haryanto

user-pic A programmer (mostly Perl 5 nowadays).