This file is indexed.

/usr/share/perl5/Data/Phrasebook/Generic.pm is in libdata-phrasebook-perl 0.35-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
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
package Data::Phrasebook::Generic;
use strict;
use warnings FATAL => 'all';
use Data::Phrasebook::Loader;
use base qw( Data::Phrasebook::Debug );
use Carp qw( croak );

use vars qw($VERSION);
$VERSION = '0.35';

=head1 NAME

Data::Phrasebook::Generic - Base class for Phrasebook Models

=head1 SYNOPSIS

    use Data::Phrasebook;

    my $q = Data::Phrasebook->new(
        class  => 'Fnerk',
        loader => 'XML',
        file   => 'phrases.xml',
        dict   => 'English',
    );

=head1 DESCRIPTION

This module provides a base class for phrasebook implementations.

=head1 CONSTRUCTOR

=head2 new

C<new> takes an optional hash of arguments. Each value in the hash
is given as an argument to a method of the same name as the key.

This constructor should B<never> need to be called directly as
Phrasebook creation should go through the L<Data::Phrasebook> factory.

Subclasses should provide at least an accessor method to retrieve values for
a named key. Further methods can be overloaded, but must retain a standard
API to the overloaded method.

All, or at least I<most>, phrasebook implementations should inherit from
B<this> class.

=cut

sub new {
    my $class = shift;
    my %hash = @_;
	$hash{loader} ||= 'Text';

    if($class->debug) {
		$class->store(3,"$class->new IN");
		$class->store(4,"$class->new args=[".$class->dumper(\%hash)."]");
	}

	my $self = bless {}, $class;

    # set default delimiters, in case custom delimiters
    # are provided in the hash
    $self->{delimiters} = qr{ :(\w+) }x;

    foreach (keys %hash) {
        $self->$_($hash{$_});
    }

    return $self;
}

=head1 METHODS

=head2 loader

Set, or get, the loader class. Uses a default if none have been
specified. See L<Data::Phrasebook::Loader>.

=head2 unload

Called by the file() and dict() methods when a fresh file or dictionary is
specified, and reloading is required.

=head2 loaded

Accessor to determine whether the current dictionary has been loaded

=head2 file

A description of a file that is passed to the loader. In most cases,
this is a file. A loader that gets its data from a database could
conceivably have this as a hash like thus:

   $q->file( {
       dsn => "dbi:SQLite:dbname=bookdb",
       table => 'phrases',
   } );

That is, which loader you use determines what your C<file> looks like.

The default loader takes just an ordinary filename.

=head2 dict

Accessor to store the dictionary to be used.

=cut

sub loader {
    my $self = shift;
    my $load = @_ ? shift : defined $self->{loader} ? $self->{loader} : 'Text';
	$self->{loader} = $load;
}
sub unload {
    my $self = shift;
    $self->{loaded} = undef;
    $self->{'loaded-data'} = undef;
    return;
}

sub loaded {
    my $self = shift;
    my $load = @_ ? $self->{loaded} = shift : $self->{loaded} ;

	# ensure we know what loader class we are getting
	$self->loader($load->class)  if($load);
	return $load;
}
sub file {
    my $self = shift;
    if(@_) {
        my $file = shift;
        if(!$self->{file} || $file ne $self->{file}) {
            $self->unload();
            $self->{file} = $file;
        }
    }
    return $self->{file};
}

sub dict {
    my $self = shift;

    if(@_) {
        my $list1 = "@_";
        my $list2 = $self->{dict} ? "@{$self->{dict}}" : '';

        if($list1 ne $list2) {
            $self->unload();
            $self->{dict} = (ref $_[0] ? $_[0] : [@_]);
        }
    }

    return($self->{dict} ? @{$self->{dict}}     : ()    )   if(wantarray);
    return($self->{dict} ? $self->{dict}->[0]   : undef );
}

=head2 dicts

Having instantiated the C<Data::Phrasebook> object class, and using the C<file>
attribute as a directory path, the object can return a list of the current
dictionaries available (provided the plugin supports it) as:

  my $pb = Data::Phrasebook->new(
    loader => 'Text',
    file   => '/tmp/phrasebooks',
  );

  my @dicts = $pb->dicts;

or

  my @dicts = $pb->dicts( $path );

=cut

sub dicts {
    my $self = shift;

    my $loader = $self->loaded;
    unless($loader) {
        $self->store(4,"->dicts loader=[".($self->loader)."]")	if($self->debug);
        $loader = Data::Phrasebook::Loader->new(
            'class' => $self->loader,
            'parent' => $self,
        );
        $self->loader($loader->class);  # so we know what we've got
    }

    # just in case it doesn't use D::P::Loader::Base
    croak("dicts() unsupported in plugin")
        unless($loader->can("dicts"));

    return $loader->dicts(@_);
}

=head2 keywords

Having instantiated the C<Data::Phrasebook> object class, using the C<dict>
attribute as required, the object can return a list of the current keywords
available (provided the plugin supports it) as:

  my $pb = Data::Phrasebook->new(
    loader => 'Text',
    file   => '/tmp/phrasebooks',
    dict   => 'TEST',
  );

  my @keywords = $pb->keywords;

or

  my @keywords = $pb->keywords( $dict );

Note the list will be a combination of the default and any named dictionary.
However, not all Loader plugins may support the second usage.

=cut

sub keywords {
    my $self = shift;

    my $loader = $self->loaded;
    if(!defined $loader) {
        $self->store(4,"->keywords loader=[".($self->loader)."]")	if($self->debug);
        $loader = Data::Phrasebook::Loader->new(
            'class' => $self->loader,
            'parent' => $self,
        );
        $self->loader($loader->class);  # so we know what we've got
    }

    # just in case it doesn't use D::P::Loader::Base
    croak("keywords() unsupported in plugin")
        unless($loader->can("keywords"));

    return $loader->keywords(@_);
}

=head2 data

Loads the data source, if not already loaded, and returns the data block
associated with the given key.

    my $data = $self->data($key);

This is typically only used internally by implementations, not the end user.

=cut

sub data {
    my $self = shift;
    my $id = shift;

    if($self->debug) {
		$self->store(3,"->data IN");
		$self->store(4,"->data id=[$id]");
	}

    return  unless($id);

    my $loader = $self->loaded;
    if(!defined $loader) {
        if($self->debug) {
            $self->store(4,"->data loader=[".($self->loader)."]");
            $self->store(4,"->data file=[".($self->file||'undef')."]");
            $self->store(4,"->data dict=[".($self->dict||'undef')."]");
        }
        $loader = Data::Phrasebook::Loader->new(
            'class' => $self->loader,
            'parent' => $self,
        );
        $self->loader($loader->class);  # so we know what we've got
        $loader->load( $self->file, $self->dict );
        $self->loaded($loader);
    }

    return $self->{'loaded-data'}->{$id} ||= do { $loader->get( $id ) };
}

=head2 delimiters

Returns or sets the current delimiters for substitution variables. Must be a
regular expression with at least one capture group.

The example below shows the default ':variable' style regex.

   $q->delimiters( qr{ :(\w+) }x );

The example below shows a Template Toolkit style regex.

   $q->delimiters( qr{ \[% \s* (\w+) \s* %\] }x );

In addition to the delimiter pattern, an optional setting to suppress missing
value errors can be passed after the pattern. If set to a true value, will 
turn any unmatched delimiter patterns to an empty string.

=cut

sub delimiters {
    my $self = shift;
    if(@_) {
        $self->{delimiters} = shift;
        $self->{blank_args} = shift || 0;
    }
        
    return $self->{delimiters};
}

1;

__END__

=head1 SEE ALSO

L<Data::Phrasebook>,
L<Data::Phrasebook::Loader>.

=head1 SUPPORT

Please see the README file.

=head1 AUTHOR

  Original author: Iain Campbell Truskett (16.07.1979 - 29.12.2003)
  Maintainer: Barbie <barbie@cpan.org> since January 2004.
  for Miss Barbell Productions <http://www.missbarbell.co.uk>.

=head1 COPYRIGHT AND LICENSE

  Copyright (C) 2003 Iain Truskett.
  Copyright (C) 2004-2013 Barbie for Miss Barbell Productions.

  This distribution is free software; you can redistribute it and/or
  modify it under the Artistic License v2.

=cut