File Coverage

blib/lib/Data/Faker.pm
Criterion Covered Total %
statement 60 62 96.7
branch 10 14 71.4
condition 2 3 66.6
subroutine 11 12 91.6
pod 3 3 100.0
total 86 94 91.4


line stmt bran cond sub pod time code
1             package Data::Faker;
2 7     7   74179 use vars qw($VERSION); $VERSION = '0.10_04';
  7         11  
  7         352  
3              
4             =head1 NAME
5              
6             Data::Faker - Perl extension for generating fake data
7              
8             =head1 SYNOPSIS
9              
10             use Data::Faker;
11              
12             my $faker = Data::Faker->new();
13              
14             print "Name: ".$faker->name."\n";
15             print "Company: ".$faker->company."\n";
16             print "Address: ".$faker->street_address."\n";
17             print " ".$faker->city.", ".$faker->us_state_abbr." ".$faker->us_zip_code."\n";
18              
19             =head1 DESCRIPTION
20              
21             This module creates fake (but reasonable) data that can be used for things
22             such as filling databases with fake information during development of
23             database related applications.
24              
25             =cut
26              
27 7     7   32 use strict;
  7         8  
  7         112  
28 7     7   21 use warnings;
  7         12  
  7         154  
29 7     7   35 use File::Spec ();
  7         11  
  7         115  
30 7     7   19 use Carp 'croak';
  7         6  
  7         1707  
31             my %plugins;
32             my @always_import;
33              
34             =head1 OBJECT METHODS
35              
36             =over 4
37              
38             =item new()
39              
40             Object constructor. As a shortcut, you can pass names of plugin modules to
41             load to new(), although this does not actually restrict the functions available
42             to the object, it just causes those plugins to be loaded if they haven't been
43             loaded already. All Data::Faker objects in one interpreter share the plugin
44             data, so that multiple objects don't multiply the memory requirements.
45              
46             =cut
47              
48             sub new {
49 14     14 1 13641 my $pack = shift;
50 14         24 my $self = {};
51 14         22 bless($self,$pack);
52 14         36 my @import = (@_,@always_import);
53 14 100       36 unless(@import) { push(@import,'*'); }
  2         4  
54 14         25 foreach my $import (@import) {
55 14         23 foreach(@INC) {
56 154         4042 for(glob(File::Spec->catfile($_, qw/Data Faker/,"$import.pm"))) {
57 168 100 66     11156 require $_ if -f $_ && -r _;
58             }
59             }
60             }
61 14         51 return $self;
62             }
63              
64 27     27   74 sub import { my $self = shift; push(@always_import,@_); }
  27         17663  
65              
66             =item methods();
67              
68             Return a list of the methods that have been provided by all of the loaded
69             plugins.
70              
71             =cut
72              
73 7     7 1 64 sub methods { return keys %Data::Faker::plugins; }
74              
75             =item register_plugin();
76              
77             Plugin modules call register_plugin() to provide data methods. See any of
78             the included plugin modules for examples.
79              
80             =cut
81              
82             sub register_plugin {
83 238     238 1 203 my $self = shift;
84 238         234 my @functions = @_;
85              
86 238         352 push(@{$Data::Faker::plugins{shift()}}, shift()) while @_;
  238         634  
87             }
88              
89 7     7   34 use vars qw($AUTOLOAD);
  7         6  
  7         1926  
90             sub AUTOLOAD {
91 244     244   21877 my $self = shift;
92 244         221 my $al = $AUTOLOAD;
93 244         729 $al =~ s/.*:://;
94 244 50       223 my @data = @{$Data::Faker::plugins{$al} || []};
  244         639  
95 244 50       334 croak "No data found for method '$al'" unless @data;
96              
97 244         485 my $data = $data[rand(@data)];
98              
99 244         161 my $result;
100 244 50       568 if(! ref($data)) {
    100          
    50          
101 0         0 $result = $data;
102             } elsif(ref($data) eq 'ARRAY') {
103 168         110 $result = $data->[rand(@{$data})];
  168         242  
104             } elsif(ref($data) eq 'CODE') {
105 76         181 $result = $data->($self);
106             } else {
107 0         0 croak "Don't know what to do with result of type '".ref($data)."'";
108             }
109 244         261 $result =~ s/\0//g;
110              
111             # replace any tokens that need expansion
112 244         197 $result =~ s/\\\$/\0/g;
113 244         440 while($result =~ /\$(\w+)/) {
114 84         105 my $what = $1;
115 84         267 my $r = $self->$what();
116 84         845 $result =~ s/\$$what/$r/;
117             }
118 244         185 $result =~ s/\0/\$/g;
119              
120             # replace any number needing expansion
121 244         183 $result =~ s/\\#/\0/g;
122 244         168 $result =~ s/#/int(rand(10))/ge;
  53         60  
123 244         179 $result =~ s/\0/#/g;
124              
125 244         2298 return $result;
126             }
127              
128       0     sub DESTROY {}
129              
130             =back
131              
132             =head1 LOADING PLUGINS
133              
134             You can specify which plugins to load by including just the base part of their
135             name as an argument when loading the module with 'use'. For example if you
136             only wanted to use data from the Data::Faker::Name module, you would load
137             Data::Faker like this:
138              
139             use Data::Faker qw(Name);
140              
141             By default any modules matching Data::Faker::* in any directory in @INC
142             will be loaded. You can also pass plugin names when calling the new() method,
143             and they will be loaded if not already in memory. See L.
144              
145             =head1 WRITING PLUGINS
146              
147             Writing a plugin to provide new kinds of data is easy, all you have to do is
148             create a module named Data::Faker::SomeModuleName that inherits from
149             Data::Faker.
150              
151             To provide data, the plugin merely needs to call the register_plugin function
152             with one or more pairs of function name and function data, like this:
153              
154             #!/usr/bin/perl -w
155             use strict;
156             use warnings;
157             use Data::Faker;
158              
159             my $faker = Data::Faker->new();
160             print "My fake data is ".$faker->some_data_function."\n";
161              
162             package Data::Faker::SomeData;
163             use base 'Data::Faker';
164              
165             __PACKAGE__->register_plugin(
166             some_data_function => [qw(foo bar baz gazonk)],
167             another_data_item => sub { return '$some_data_function' },
168             );
169              
170             The first argument is the method that will be made available to your object,
171             the second is a data source. If the data source is not a reference, it will
172             simply be returned as the data, if it is a reference to an array, a random
173             element from the array will be returned, and if it is a subroutine reference,
174             the subroutine will be run and the results will be returned. The data that
175             your data source provides is checked for two things, tokens (that look like
176             perl variables, starting with a $), and numeric indicators (#). Any tokens
177             found will be replaced with their values, and any numeric indicators will be
178             replaced with random numbers. You can include a literal $ or # by prefacing
179             it with a backslash. If you load more than one module that defines the same
180             function, it has an additive effect, when the function is called one of the
181             data sources provided will be selected at random and then it will be called
182             to get a piece of data.
183              
184             Some data source examples:
185              
186             __PACKAGE__->register_plugin(
187             age => ['#','##'],
188             monetary_amount => ['\$####.##','\$###.##', '\$##.##', '\$#.##'],
189             adult_age => sub { int(rand(70)+18) },
190             );
191              
192             If your data source is a code reference, it will receive the calling object
193             as an argument so you can build data out of other data if you need to. See
194             L for some examples of this.
195              
196             =head1 BUGS AND KNOWN ISSUES
197              
198             There is no way to selectively remove data sources from a plugin that was
199             loaded, even if you didn't load it.
200              
201             =head1 SEE ALSO
202              
203             Text::Lorem
204              
205             =head1 AUTHOR
206              
207             Jason Kohles, Eemail@jasonkohles.comE
208              
209             =head1 COPYRIGHT AND LICENSE
210              
211             Copyright 2004-2005 by Jason Kohles
212              
213             This library is free software; you can redistribute it and/or modify
214             it under the same terms as Perl itself.
215              
216             =cut
217              
218             1;