nysus has asked for the wisdom of the Perl Monks concerning the following question:

I've written a test that inputs keystrokes into the terminal. To do this, I create a fork of my test code. The input from the terminal modifies the object. When my fork returns, however, the object is not modified. How do I return the object from the fork to my original test process?

# CODE: my $obj = ''; lives_ok { $obj = Commander->new(valid_chars => [ qw ( a b c d ) ] ) } + 'Can pass it an array of valid chars'; lives_ok { issue_cmd("abcd\n") } 'Can get a command terminated with ne +w line'; is ($obj->last_cmd, 'abcd', 'got expected input'); # this fails, retur +ns empty string # support methods sub jam { $TIOCSTI = 0x80017472; for (split(//, $_[0])) { ioctl(STDIN, $TIOCSTI, $_) || die "bad TIOCSTI: $!"; } } sub issue_cmd { my $cmd = shift; my $pid = fork(); if (!defined $pid) { die "Cannot fork: $!"; } elsif ($pid == 0) { $obj->get_cmd; exit 0; } else { jam($cmd); waitpid $pid, 0; } }

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: Modifying an object in a fork
by 1nickt (Canon) on Mar 11, 2018 at 23:45 UTC

    It's trivial using the mighty MCE::Shared by marioroy, two extra lines:

    package MyClass { use Moose; has foo => ( is => 'rw', default => 'bar' ); }; package main { use strict; use warnings; use feature 'say'; use MCE::Shared; my $obj = MCE::Shared->share({ module => 'MyClass' }); say 'Before forking: ' . $obj->foo; my $pid = fork; if ( $pid == 0 ) { $obj->foo('baz'); exit; } else { waitpid $pid, 0; } say 'After forking: ' . $obj->foo; };
    Output:
    $ perl 1210687.pl Before forking: bar After forking: baz
    For details see the documentation on sharing objects between processes with MCE::Shared.

    Hope this helps!


    The way forward always starts with a minimal test.

      Hi 1nickt,

      It's trivial using the mighty MCE::Shared ...

      Also, see the logger and Tie::File MCE::Shared demonstrations. The object class, like in your demo, is constructed under the shared-manager process where it lives. How it works is that any interaction with the object is then possible via the OO interface only.

      Regards, Mario

      Thanks, hadn't heard of that module before.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

Re: Modifying an object in a fork
by karlgoethebier (Abbot) on Mar 12, 2018 at 11:15 UTC

    Dr Wisenheimer's lightweight edition:

    #!/usr/bin/env perl use strict; use warnings; use feature qw(say); use MCE::Shared; package MyClass { use Class::Tiny { foo => q(bar) }; }; my $object = MCE::Shared->share( { module => 'MyClass' } ); say q(Before forking: ) . $object->foo; my $pid = fork; if ( $pid == 0 ) { $object->foo(q(baz)); exit; } else { waitpid $pid, 0; } say q(After forking: ) . $object->foo; __END__

    I don't know if this helps. At least it is funny.

    Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Re: Modifying an object in a fork
by Anonymous Monk on Mar 11, 2018 at 22:34 UTC

    How do I return the object from the fork to my original test process?

    You use threads

      Threads aren't compiled into my install. I guess to keep things simple I can just write the object to a disk with storable.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

        Then use forks :)