This file is indexed.

/usr/share/perl5/IO/TieCombine.pm is in libio-tiecombine-perl 1.005-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
use strict;
use warnings;
package IO::TieCombine;
# ABSTRACT: produce tied (and other) separate but combined variables
$IO::TieCombine::VERSION = '1.005';
use Carp ();
use IO::TieCombine::Handle;
use IO::TieCombine::Scalar;
use Symbol ();

#pod =head1 SYNOPSIS
#pod
#pod First, we set up a bunch of access points:
#pod
#pod   my $hub = IO::TieCombine->new;
#pod
#pod   my $str_ref  = $hub->scalar_ref('x');
#pod   my $fh       = $hub->fh('x');
#pod   my $callback = $hub->callback('x');
#pod
#pod   tie my $scalar, $hub, 'x';
#pod   tie local *STDOUT, $hub, 'x';
#pod
#pod   tie local *STDERR, $hub, 'err';
#pod
#pod Then we write to things:
#pod
#pod   $$str_ref .= 'And ';
#pod   print $fh "now ";
#pod   $callback->('for ');
#pod   $scalar .= 'something ';
#pod   print "completely ";
#pod   warn "different.\n";
#pod
#pod And then:
#pod
#pod   $hub->combined_contents;    # And now for something completely different.
#pod   $hub->slot_contents('x');   # And now for something completely
#pod   $hub->slot_contents('err'); # different.
#pod
#pod B<ACHTUNG!!>  Because of a serious problem with Perl 5.10.0, output sent to a
#pod tied filehandle using C<say> B<will not have the expected newline>.  5.10.1 or
#pod later is needed.  Since 5.10.0 is broken in so many other ways, you should
#pod really upgrade anyway.
#pod
#pod B<ACHTUNG!!>  Because of a different problem with Perls 5.10.1 - 5.16.3, if you
#pod send output to a tied filehandle using C<say>, and C<$\> is undefined (which is
#pod the default), B<< C<$\> will not be restored to C<undef> after the C<say> >>!
#pod This means that once you've used C<say> to print to I<any> tied filehandle, you
#pod have corrupted the global state of your program.  Either start your program by
#pod setting C<$\> to an empty string, which should be safe, or upgrade to 5.18.0.
#pod
#pod =cut

#pod =method new
#pod
#pod The constructor takes no arguments.
#pod
#pod =cut

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

  my $self = {
    combined => \(my $str = ''),
    slots    => { },
  };

  bless $self => $class;
}

#pod =method combined_contents
#pod
#pod This method returns the contents of all collected data.
#pod
#pod =cut

sub combined_contents {
  my ($self) = @_;
  return ${ $self->{combined} };
}

#pod =method slot_contents
#pod
#pod   my $str = $hub->slot_contents( $slot_name );
#pod
#pod This method returns the contents of all collected data for the named slot.
#pod
#pod =cut

sub slot_contents {
  my ($self, $name) = @_;
  Carp::confess("no name provided for slot_contents") unless defined $name;

  Carp::confess("no such output slot exists")
    unless exists $self->{slots}{$name};

  return ${ $self->{slots}{$name} };
}

sub _slot_ref {
  my ($self, $name) = @_;
  Carp::confess("no slot name provided") unless defined $name;

  $self->{slots}{$name} = \(my $str = '') unless $self->{slots}{$name};
  return $self->{slots}{$name};
}

sub _tie_args {
  my ($self, $name) = @_;
  return {
    slot_name    => $name,
    combined_ref => $self->{combined},
    output_ref   => $self->_slot_ref($name),
  };
}

#pod =method clear_slot
#pod
#pod   $hub->clear_slot( $slot_name );
#pod
#pod This sets the slot back to an empty string.
#pod
#pod =cut

sub clear_slot {
  my ($self, $slot_name) = @_;
  ${ $self->_slot_ref($slot_name) } = '';
  return;
}

#pod =method fh
#pod
#pod   my $fh = $hub->fh( $slot_name );
#pod
#pod This method returns a reference to a tied filehandle.  When printed to, output
#pod is collected in the named slot.
#pod
#pod =cut

sub fh {
  my ($self, $name) = @_;

  my $sym = Symbol::gensym;
  my ($class, @rest) = $self->_tie_fh_args($name);
  tie *$sym, $class, @rest;
  return $sym;
}

sub TIEHANDLE {
  my ($self, @args) = @_;
  my ($class, @rest) = $self->_tie_fh_args(@args);

  return $class->TIEHANDLE(@rest);
}

sub _tie_fh_args {
  my ($self, $name) = @_;
  return ('IO::TieCombine::Handle', $self->_tie_args($name));
}

#pod =method scalar_ref
#pod
#pod   my $str_ref = $hub->scalar_ref( $slot_name );
#pod
#pod This method returns a reference to scalar.  When appended to, the new content
#pod is collected in the named slot.  Attempting to alter the string other than by
#pod adding new content to its end will result in an exception.
#pod
#pod =cut

sub scalar_ref {
  my ($self, $name) = @_;
  my ($class, @rest) = $self->_tie_scalar_args($name);
  tie my($tie), $class, @rest;
  return \$tie;
}

sub TIESCALAR {
  my ($self, @args) = @_;
  my ($class, @rest) = $self->_tie_scalar_args(@args);

  return $class->TIESCALAR(@rest);
}

sub _tie_scalar_args {
  my ($self, $name) = @_;
  return ('IO::TieCombine::Scalar', $self->_tie_args($name));
}

#pod =method callback
#pod
#pod   my $code = $hub->callback( $slot_name );
#pod
#pod =cut

sub callback {
  my ($self, $name) = @_;
  my $slot = $self->_slot_ref($name);
  return sub {
    my ($value) = @_;

    ${ $slot             } .= $value;
    ${ $self->{combined} } .= $value;
  }
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

IO::TieCombine - produce tied (and other) separate but combined variables

=head1 VERSION

version 1.005

=head1 SYNOPSIS

First, we set up a bunch of access points:

  my $hub = IO::TieCombine->new;

  my $str_ref  = $hub->scalar_ref('x');
  my $fh       = $hub->fh('x');
  my $callback = $hub->callback('x');

  tie my $scalar, $hub, 'x';
  tie local *STDOUT, $hub, 'x';

  tie local *STDERR, $hub, 'err';

Then we write to things:

  $$str_ref .= 'And ';
  print $fh "now ";
  $callback->('for ');
  $scalar .= 'something ';
  print "completely ";
  warn "different.\n";

And then:

  $hub->combined_contents;    # And now for something completely different.
  $hub->slot_contents('x');   # And now for something completely
  $hub->slot_contents('err'); # different.

B<ACHTUNG!!>  Because of a serious problem with Perl 5.10.0, output sent to a
tied filehandle using C<say> B<will not have the expected newline>.  5.10.1 or
later is needed.  Since 5.10.0 is broken in so many other ways, you should
really upgrade anyway.

B<ACHTUNG!!>  Because of a different problem with Perls 5.10.1 - 5.16.3, if you
send output to a tied filehandle using C<say>, and C<$\> is undefined (which is
the default), B<< C<$\> will not be restored to C<undef> after the C<say> >>!
This means that once you've used C<say> to print to I<any> tied filehandle, you
have corrupted the global state of your program.  Either start your program by
setting C<$\> to an empty string, which should be safe, or upgrade to 5.18.0.

=head1 METHODS

=head2 new

The constructor takes no arguments.

=head2 combined_contents

This method returns the contents of all collected data.

=head2 slot_contents

  my $str = $hub->slot_contents( $slot_name );

This method returns the contents of all collected data for the named slot.

=head2 clear_slot

  $hub->clear_slot( $slot_name );

This sets the slot back to an empty string.

=head2 fh

  my $fh = $hub->fh( $slot_name );

This method returns a reference to a tied filehandle.  When printed to, output
is collected in the named slot.

=head2 scalar_ref

  my $str_ref = $hub->scalar_ref( $slot_name );

This method returns a reference to scalar.  When appended to, the new content
is collected in the named slot.  Attempting to alter the string other than by
adding new content to its end will result in an exception.

=head2 callback

  my $code = $hub->callback( $slot_name );

=head1 AUTHOR

Ricardo SIGNES <rjbs@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2015 by Ricardo SIGNES.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut