I'm trying to get this Perl code to work correctly and I believe I just need to get my references right. I would appreciate any feedback on how to use references, but if this code can't be made to work without API changes I would also appreciate feedback on how to change the surrounding APIs to support the data types I need.
I'm trying to add a new test to the PostgreSQL test suite. The code in question runs a subprocess and stores the process arguments in an array literal in a hash. for example:
my %pgdump_runs = (
defaults => {
dump_cmd => [
'pg_dump', '--no-sync',
'-f', "$tempdir/defaults.sql",
'postgres',
],
},
# and others
)
That array gets passed to a helper library like so:
$node->command_ok(\@{ $pgdump_runs{$run}->{dump_cmd} },
"$run: pg_dump runs");
The helper library keeps passing the array down:
sub command_ok
{
my ($cmd, $test_name) = @_;
my $result = run_log($cmd);
and then finally calling IPC::Run:
sub run_log
{
return IPC::Run::run(@_);
}
To write my test case I have to pipe the output of a command to a file descriptor that does not support seeking. It looks like the IPC::Run module supports piping for you. Here's the example for the docs:
run \@cmd1, '|', \@cmd2;
But I tried a bunch of different ways to try and structure my array literal and none of them worked. For example, I tried this and I believe it gave me an ARRAY(0xFFFFFFFF)
error:
dump_cmd => [
['pg_dump', 'db'],
'|',
['pg_restore', 'db2'],
],
How can I get this code to set up multiple sub-processes with piping?
UPDATE: I tried out ikegami's suggestion: the command_ok
function can only have two arguments passed to it, so that doesn't work (you have to pass an array reference for the first argument).
UPDATE: turning on IPC:Run's debug functionality I can see how it's trying to interpret my command line. Instead of dereferencing the array it's trying to stringify (?) it and exec that string as an executable:
1070 IPC::Run 0002 01234567890- [#11(59856)]: parsing [ 'ARRAY(0x7ff3016f1090)', '|', 'ARRAY(0x7ff3016f1510)', '>/Users/david/src/pg_bug/postgres/foo' ]