Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re^4: shedding a bash wrapper and updating to Path::Tiny

by kevbot (Priest)
on Jul 13, 2018 at 05:49 UTC ( #1218421=note: print w/replies, xml ) Need Help??


in reply to Re^3: shedding a bash wrapper and updating to Path::Tiny
in thread shedding a bash wrapper and updating to Path::Tiny

Hello Datz_cozee75,

Here are a few comments.

  • Path::Tiny has a method for getting the absolute path of the current working directory, so path(".")->absolute; with  Path::Tiny->cwd;
  • You do not need to quote the variables when you create a new path, so code like this path( "$current", "$to", "$ts" ) can be changed to code like this path( $current, $to, $ts )
  • You do not need to use stringify on a path before printing it, so code like this say "string abs from is $string_abs_from"; can be changed to use the variable that contains the Path::Tiny object like this say "string abs from is $abs_from";. Generally, Path::Tiny objects will stringify on their own when necessary. However, there may be times when you are passing a Path::Tiny object to another method (for example, a method from a different CPAN package) you may sometimes need to stringify the path first.
  • I like to use named variables in my foreach loops, so I made some changes to reflect this.
  • The Path::Tiny children method can be given an argument of a regular expression, where only children that match the regular expression are returned. This allowed me to simplify your code a bit.

Here is the modified code. Please note that this code is untested and I did this quickly, so it may need some small adjustments and there may be some typos. Please be sure that you have a backup of your data before running this code.

#!/usr/bin/perl -w use strict; use 5.010; use utf8; use open qw/:std :utf8/; use Path::Tiny; my %vars = ( place => 'Vancouver', book => 'Медитац&# +1080;я на perlем', chapter => 'populated title', print_module => 1, script_file => undef, server_dir => 'perlmonks', image_dir => 'pmimage', ); # This script clones the template directory in $1 to $2. # Some names need munging. # $from is a populated child directory; $to is child dir to be create +d. $pop is the folder with the data. my ( $from, $to, $pop ) = @ARGV; my $ts = "template_stuff"; my $current = Path::Tiny->cwd; #say "current is $current"; say "-------------"; say "making directories"; # define the paths within the target directory: my $abs_to = path( $current, $to, $ts ); $abs_to->mkpath; say "abs to template is $abs_to"; # $from template directory: my $abs_from = path( $current, $from, $ts ); say "string abs from is $abs_from"; say "-------------"; say "copying files"; foreach my $child ( $abs_from->children(qr/\.(txt|pm|css|tmpl|pl|sh)$/ +) { next unless $child->is_file; my $base = $child->basename; #syntax is from to to my $return = path($child)->copy( $abs_to, $base ); if ($base =~ m/\.(pl|sh)$/) { $return->chmod(0755); } say "return is $return"; } say "-------------"; # copy css file to template with munged name foreach my $child ( $abs_from->children ) { my $base = $child->basename; if ( $base =~ m/^$from(\d*)\.css$/ ) { #say "matching is $base"; say "dollar one is $1"; my $munge = $to . "1" . ".css"; say "munge is $munge"; my $name = path( $abs_to, $munge ); say "name is $name"; #syntax is from to to my $return = path( $abs_from, $base )->copy($name); say "return2 is $return"; } } ## munge and copy executable, change permissions say "-------------"; my $d = path( $current, $from ); # @matching will be an array of Path::Tiny objects my @matching = $d->children(qr/$from(\d*)\.pl$/i); @matching = sort @matching; say "matched is @matching"; my $winner = pop @matching; my $newfile = "${to}1.pl"; my $b = path( $current, $to, $newfile ); print "b is $b\n"; # $winner will already be a Path::Tiny object my $return3 = $winner->copy("$b"); say "return3 is $return3"; $return3->chmod(0755); say "end of clone"; my $path = path(qw(master_list 2013 North_America)); # prints 'master_list/2013/North_America'; say $path; # prints 'master_list/2013/North_America' on unix, # 'master_list\2013\North_America' on win32 say $path->canonpath; # prints /home/santa/master_list/2013/North_America when $CWD is /home +/santa say $path->absolute; # prints 'master_list/2013' say $path->parent; # prints 'master_list/2013/North_America/Vancouver/ETHER' say $path->child( 'Vancouver', 'ETHER' ); my $tempdir = Path::Tiny->tempdir('delivery_list_XXXXXX'); my $tempfile = Path::Tiny->tempfile( TEMPLATE => 'delivery_list_XXXXXX', suffix => +'.bin' ); my $scratch_file = $tempdir->child( 'batch_01', 'scratchfile.txt' )->t +ouchpath; chdir $tempdir unless $tempdir->subsumes( Path::Tiny->cwd ); system("pwd &"); my $abs_pop = path( $current, $pop, $ts ); say "string abs pop is $abs_pop"; foreach my $child ( $abs_pop->children ) { next $child->is_dir; say "e is $child"; my $base_dir = $child->basename; say "base dir is $base_dir"; my $folder = path( $current, $to, $ts, $base_dir )->mkpath; say "folder is $folder"; say "string folder is $folder"; my $pop_from = $child; next if( $child =~ m/logs/; foreach $pchild ( $pop_from->children ) { say "default is $pchild\n"; my $base = $pchild->basename; say "base is $base"; my $to_name = path( $folder, $base ); say "to name is $to_name"; my $return4 = path($pchild)->copy($to_name); say "return4 is $return4"; } } my $exec_path = path( $current, $to ); my $return5 = chdir($exec_path); say "return5 is $return5"; system("pwd "); system("ls "); system ("./$newfile ");

Replies are listed 'Best First'.
Re^5: shedding a bash wrapper and updating to Path::Tiny
by Aldebaran (Chaplain) on Jul 25, 2018 at 05:45 UTC

    Thx kevbot, this script really added a lot of polish to the Path::Tiny idioms, but I could not get away from stringifying one line. After you make the method call to mkdir, it's gonna return 1 if successful, so the line with the mkdir call isn't any good for building a path in subsequent path statements. First is the script and then the output:

    Resulting html page shows successful cloning. I appreciate your comments, and my humble script is vastly-improved over the lifetime of this thread.

      Hello Datz_cozee75,

      I'm glad you found my post helpful. I don't see mkdir used anywhere in your code. When you refer to mkdir, I assume you are referring to the mkpath method from Path::Tiny that you use in a couple places (not to be confused with the perl function mkdir). So, code like this may need to be changed to do what you want...

      my $folder = path( $current, $to, $ts, $base_dir )->mkpath;
      The documentation for the Path::Tiny mkpath method states that it returns the list of directories created or an empty list if the directories already exist, just like make_path.. So perhaps this would be more useful,
      my $folder_path = path( $current, $to, $ts, $base_dir ); $folder_path->mkpath; # This will print the path regardless if the path already existed or n +ot print "My folder path is $folder_path\n";
      If you wanted to check the return value of the mkpath method, you could store it in a scalar like this,
      my $mkpath_return_value = $folder_path->mkpath; # The value of $mkpath_return_value will be equal to the number of dir +s created (since the return value will be a list that is forced into # scalar context), or it will be equal to zero if the path already exi +sted.
      or if you wanted the list of dirs that were created you could do this,
      my @dirs = $folder_path->mkpath;

        Gosh, kevbot, I try to be done making mistakes for one thread, so I hope that we can address this last one. Indeed, in my write-up I did conflate perl's mkdir with Path::Tiny's mkpath method. When one uses the latter in list context, one can build subsequent paths with it:

        my @dirs = path( $current, $to, $ts, $base_dir )->mkpath; say "dirs are @dirs"; foreach my $pchild ( $pop_from->children ) { my $base = $pchild->basename; say "base is $base"; my $to_name = path( @dirs, $base );

        I didn't find all that many examples for using Path::Tiny out there, so let's hope that others get something out of this.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1218421]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2019-07-22 23:06 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    If you were the first to set foot on the Moon, what would be your epigram?






    Results (22 votes). Check out past polls.

    Notices?