From: Uri Guttman Date: Thu, 5 May 2011 05:19:03 +0000 (-0400) Subject: added prefix option to read_dir X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=urisagit%2FPerl-Docs.git;a=commitdiff_plain;h=6ccd701d57febc2949c65f461cb17dfa29471d52 added prefix option to read_dir added chomp option to read_file in lines mode added pod for both --- diff --git a/lib/File/Slurp.pm b/lib/File/Slurp.pm index 41600ff..63df851 100755 --- a/lib/File/Slurp.pm +++ b/lib/File/Slurp.pm @@ -3,12 +3,13 @@ package File::Slurp; use 5.6.2 ; use strict; +use warnings ; use Carp ; use Exporter ; use Fcntl qw( :DEFAULT ) ; use POSIX qw( :fcntl_h ) ; -use Symbol ; +#use Symbol ; use vars qw( @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION ) ; @ISA = qw( Exporter ) ; @@ -171,7 +172,8 @@ sub read_file { #printf "RD: BINARY %x MODE %x\n", O_BINARY, $mode ; - $read_fh = gensym ; + $read_fh = local( *FH ) ; +# $read_fh = gensym ; unless ( sysopen( $read_fh, $file_name, $mode ) ) { @_ = ( $opts, "read_file '$file_name' - sysopen: $!"); goto &_error ; @@ -197,20 +199,6 @@ sub read_file { } } - -# if ( $size_left < 10000 && keys %{$opts} == 0 && !wantarray ) { - -# my $read_cnt = sysread( $read_fh, my $buf, $size_left ) ; - -# unless ( defined $read_cnt ) { - -# @_ = ( $opts, "read_file '$file_name' - small2 sysread: $!"); -# goto &_error ; -# } - -# return $buf ; -# } - # infinite read loop. we exit when we are done slurping while( 1 ) { @@ -256,6 +244,8 @@ sub read_file { my @lines = length(${$buf_ref}) ? ${$buf_ref} =~ /(.*?$sep|.+)/sg : () ; + chomp @lines if $opts->{'chomp'} ; + # caller wants an array ref return \@lines if $opts->{'array_ref'} ; @@ -452,7 +442,8 @@ sub write_file { # open the file and handle any error. - $write_fh = gensym ; + $write_fh = local( *FH ) ; +# $write_fh = gensym ; unless ( sysopen( $write_fh, $file_name, $mode, $perms ) ) { @_ = ( $opts, "write_file '$file_name' - sysopen: $!"); @@ -744,6 +735,11 @@ sub read_dir { @dir_entries = grep( $_ ne "." && $_ ne "..", @dir_entries ) unless $opts->{'keep_dot_dot'} ; + if ( $opts->{'prefix'} ) { + + substr( $_, 0, 0, "$dir/" ) for @dir_entries ; + } + return @dir_entries if wantarray ; return \@dir_entries ; } @@ -797,33 +793,32 @@ File::Slurp - Simple and Efficient Reading/Writing/Modifying of Complete Files use File::Slurp; # read in a whole file into a scalar - my $text = read_file( 'filename' ) ; # read in a whole file into an array of lines - my @lines = read_file( 'filename' ) ; # write out a whole file from a scalar - write_file( 'filename', $text ) ; # write out a whole file from an array of lines - write_file( 'filename', @lines ) ; # Here is a simple and fast way to load and save a simple config file # made of key=value lines. - my %conf = read_file( $file_name ) =~ /^(\w+)=(\.*)$/mg ; write_file( $file_name, {atomic => 1}, map "$_=$conf{$_}\n", keys %conf ; # insert text at the beginning of a file - prepend_file( 'filename', $text ) ; -# read in a whole directory of file names (skipping . and ..) +# in-place edit to replace all 'foo' with 'bar' in file + edit_file { s/foo/bar/g } 'filename' ; +# in-place edit to delete all lines with 'foo' from file + edit_file_lines sub { $_ = '' if /foo/ }, 'filename' ; + +# read in a whole directory of file names (skipping . and ..) my @files = read_dir( '/path/to/dir' ) ; =head1 DESCRIPTION @@ -911,6 +906,12 @@ slurped file. The following two calls are equivalent: my $lines_ref = read_file( $bin_file, array_ref => 1 ) ; my $lines_ref = [ read_file( $bin_file ) ] ; +=head3 chomp + +If this boolean option is set, the lines are chomped. This only +happens if you are slurping in a list context or using the +C option. + =head3 scalar_ref If this boolean option is set, the return value (only in scalar @@ -1115,6 +1116,47 @@ explicitly. prepend_file( $file, \@lines ) ; prepend_file( $file, { binmode => 'raw:'}, $bin_data ) ; + +=head2 edit_file, edit_file_lines + +These subs read in a file into $_, execute a code block which should +modify $_ and then write $_ back to the file. The difference between +them is that C reads the whole file into $_ and calls the +code block one time. With C each line is read into $_ +and the code is called for each line. In both cases the code should +modify $_ if desired and it will be written back out. These subs are +the equivilent of the -pi command line options of Perl but you can +call them from inside your program and not fork out a process. + +The first argument to C and C is a code +block or a code reference. The code block is not followed by a comma +(as with grep and map) but a code reference is followed by a +comma. See the examples below for both styles. The next argument is +the filename. The last argument is an optional hash reference and it +contains key/values that can modify the behavior of +C. + +Only the C and C options are supported. The +C call has the C option set so you will always +have a consistant file. See above for more about those options. + +Each group of calls below show a Perl command line instance and the +equivilent calls to C and C. + + perl -0777 -pi -e 's/foo/bar/g' filename + use File::Slurp ; + edit_file { s/foo/bar/g } 'filename' ; + edit_file sub { s/foo/bar/g }, 'filename' ; + edit_file \&replace_foo, 'filename' ; + sub replace_foo { s/foo/bar/g } + + perl -pi -e '$_ = '' if /foo/' filename + use File::Slurp ; + edit_file_lines { $_ = '' if /foo/ } 'filename' ; + edit_file_lines sub { $_ = '' if /foo/ }, 'filename' ; + edit_file \&delete_foo, 'filename' ; + sub delete_foo { $_ = '' if /foo/ } + =head2 read_dir This sub reads all the file names from directory and returns them to @@ -1143,6 +1185,15 @@ list of files. my @all_files = read_dir( '/path/to/dir', keep_dot_dot => 1 ) ; +=head3 prefix + +If this boolean option is set, the string "$dir/" is prefixed to each +dir entry. This means you can directly use the results to open +files. A common newbie mistake is not putting the directory in front +of entries when opening themn. + + my @paths = read_dir( '/path/to/dir', prefix => 1 ) ; + =head2 EXPORT read_file write_file overwrite_file append_file read_dir