0

How can I call another subroutine from existing subroutine just after the return statement in perl. I dont want to call before the return statement as it is taking time to render. I do not want to wait. return it and then call another subroutine before the exit. Is it possible in perl?

Dumb
  • 83
  • 1
  • 10
  • 2
    Please explain your problem better. As stated, your request makes no sense. You can't do something before the sub is exited but after it executes a `return`, because the whole point of `return` is to exit the sub. – ikegami Jun 05 '19 at 10:37
  • Write a wrapper for the routine from which you want to return without undue wait, in which you call that routine (and so it returns) and then call the other one. – zdim Jun 05 '19 at 10:44
  • Can I use hook feature of Mojolicious? – Dumb Jun 05 '19 at 10:45
  • @zdim Can you please give me an example of what you are suggesting – Dumb Jun 05 '19 at 10:52
  • It sounds like what you want is an `after` method modifier. If you use Moose inside of Mojolicious, you have the Moose implementation available. If you don't, you could use Class::Method::Modifiers. If you're talking about Actions in Mojo, I am not sure what willl happen if you combine that. If you can alter the sub you want something to execute after, you can always go `return do{ foo(); $original_return_value }` – simbabque Jun 05 '19 at 11:55
  • Thanks @simbabque. But can I do something like return do{$original_return_value; foo() } – Dumb Jun 05 '19 at 12:13
  • That would discard the original return value and return the return value of `foo()`. So that doesn't make sense. – simbabque Jun 05 '19 at 13:38
  • Like `sub wrapper { original(); slow() };` and add handling of returns etc. – zdim Jun 05 '19 at 16:05

2 Answers2

5

You can fork and run your subroutine in a new process while the original process is returning.

sub do_something {
    my ($var1, $var2, $var3) = @_;
    my $output = ...

    if (fork() == 0) {
        # child process
        do_something_else_that_takes_a_long_time();
        exit;
    }
    # still the parent process
    return $output;
}
mob
  • 117,087
  • 18
  • 149
  • 283
1

Your question is tagged as Moose, so here is how you do what you want with a method modifier. The after modifier runs after a sub is, but its return value is ignored.

package Foo;
use Moose;

sub frobnicate {
  my $self = shift;

  # ...

  return 123;
}

after frobnicate => sub {
  my ($self, $rv) = @_;

  $self->barnicate;
};

1;

Now whenever frobnicate is done, barnicate will be called.

simbabque
  • 53,749
  • 8
  • 73
  • 136