RedirectStack.pm 3.03 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
=pod

=head1 NAME

    Bio::EnsEMBL::Hive::Utils::RedirectStack

=head1 DESCRIPTION

    Sometimes there is a need to intercept STDOUT/STDERR and log it in multiple files,
    depending on which of the nested objects is "in control" at the moment.

    In Hive when a Worker is running a job it logs into a job's file, but between jobs it logs into its own file.
    This class implements a convenient stack of proxy file descriptors that lets you log STDOUT or STDERR in various files.

=head1 USAGE EXAMPLE

17
    use RedirectStack;
18

19
    my $rs_stdout = RedirectStack->new(\*STDOUT);
20

21
    print "Message 1\n";            # gets displayed on the screen
22

23
    $rs_stdout->push('foo');
24

25
        print "Message 2\n";            # goes to 'foo'
26

27
        $rs_stdout->push('bar');
28

29
            print "Message 3\n";            # goes to 'bar'
30

31
            system('echo subprocess A');    # it works for subprocesses too
32

33
            $rs_stdout->pop;
34

35
        print "Message 4\n";            # goes to 'foo'
36

37
        system('echo subprocess B');    # again, works for subprocesses as well
38

39
        $rs_stdout->push('baz');
40

41 42 43 44 45
            print "Message 5\n";            # goest to 'baz'

            $rs_stdout->pop;

        print "Message 6\n";            # goes to 'foo'
46 47 48

        $rs_stdout->pop;

49 50 51
    print "Message 7\n";            # gets displayed on the screen

=head1 LICENSE
52

53
    Copyright [1999-2014] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
54

55 56 57 58 59 60 61 62 63 64 65 66
    Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software distributed under the License
    is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and limitations under the License.

=head1 CONTACT

    Please contact ehive-users@ebi.ac.uk mailing list with questions/suggestions.
67 68 69 70

=cut


71 72
package Bio::EnsEMBL::Hive::Utils::RedirectStack;

73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
use strict;
use warnings;

sub new {
    my ($class, $fh) = @_;

    die "Please supply filehandle to be redirected as the only argument" unless $fh;

    return bless {
        '_fh'       => $fh,
        '_sp'       => 0,
        '_handle_stack' => [],
    }, $class;
}

sub push {
    my ($self, $filename) = @_;

    die "Please supply filename to be redirected into as the only argument" unless $filename;

    unless($self->{_handle_stack}[$self->{_sp}]) {
        open $self->{_handle_stack}[$self->{_sp}], '>&', $self->{_fh};
    }
    close $self->{_fh};
    open $self->{_fh}, '>', $filename;
    ++$self->{_sp};
}

sub pop {
    my ($self) = @_;

    if($self->{_handle_stack}[$self->{_sp}]) {
        close $self->{_handle_stack}[$self->{_sp}];
        delete $self->{_handle_stack}[$self->{_sp}];
    }
    close $self->{_fh};
    open $self->{_fh}, '>&', $self->{_handle_stack}[--$self->{_sp}];
}

1;