in reply to Re: create clone script for utf8 encoding
in thread create clone script for utf8 encoding

Showing what you've tried, even unsuccessful attempts, will often help us to better help you. We can see where your thought process (via code logic) was heading and perhaps steer you on a better course. A few minor tweaks may turn "awful" into "awesome". It can also help future readers who might be trying similar things.

If you really want to see some broken code, I've got one more problem with regex for highest number; it's actually this related regex that is failing for me as it rounds the bend into double digit territory.

I have a page like a garden-variety webpage, where it's clearly not a finished product, but it won't give me a number beyond ten, using this:

sub highest_number{ use strict; use File::Basename; use Cwd; my ($aref, $filetype, $word) = @_; my $number; my @matching; my $ext = ".".$filetype; push (@matching, 0); #min returned value for my $file (@{$aref}) { #print "file is $file\n"; if ($file =~ /^$word(\d*)$ext$/){ #print "matching is $file\n"; push (@matching, $1); } } @matching = sort @matching; my $winner = pop @matching; return $winner }

Did I not promise awful? I don't even got how this code could run without a semi-colon after $winner .

But I have made progress on the central task, and thank you for your response. Until I can find a meaningful name and place for it, I have called it 1.a.pl:

$ history | tail - 10 ==> standard input <== 1987 pt 1.a.pl ... 1990 ./1.a.pl 1.k.pl 1991 rm 2.k.pl 1992 ./1.a.pl 1.k.pl 1993 file -i *.pl 1994 cat 1.manifest ... 1996 history | tail - 10 tail: cannot open '10' for reading: No such file or directory $

This is getting there:

$ cat 1.a.pl #!/usr/bin/perl -w use 5.011; use Path::Tiny; use Encode; use utf8; # a la François use open OUT => ':encoding(utf8)'; use open ':std'; # This script increments and clones the file in $1. ## enabling cyrillic ## decode argv and current say "argv is @ARGV"; foreach (@ARGV) { say "before decode is $_"; $_ = decode( 'UTF-8', $_ ); say "after decode is $_"; } my (@in_files) = @ARGV; my $current = Path::Tiny->cwd; $current = decode( 'UTF-8', $current ); say "current is $current"; say "-------------"; say "in_file: @in_files"; for (@in_files) { my $tiny_in = path($_); ## use Path::Tiny my $file_contents = $tiny_in->slurp_utf8; $_ =~ m/^(\d+)(.*)$/; my $number = $1; my $rest = $2; my $increment = $number + 1; my $new_base = $increment . $rest; say "new base is $new_base"; ## use Path::Tiny to create new file my $save_file = path( $current, $new_base )->touchpath; say "save path is $save_file"; my $return = $tiny_in->copy($save_file); $return->chmod(0755); say "return is $return"; ## write to local manifest my $manifest_name = "1.manifest"; path($manifest_name)->append_utf8( $new_base . "\n" ); system "cat $manifest_name"; system "cat $save_file"; } $

It looks like I got the spacing on the manifest file squared away:

$ cat 1.manifest 2.haukex.pl 3.haukex.pl 4.haukex.pl4.ping3a.pl5.haukex.pl5.ping3a.pl2.k.pl/n2.k.pl 3.k.pl $

Replies are listed 'Best First'.
Re^3: create clone script for utf8 encoding
by kcott (Archbishop) on Dec 19, 2018 at 07:58 UTC
    "I don't even got how this code could run without a semi-colon after $winner ."

    It's the last line of "sub highest_number { ... }". Technically, that is terminated by the final brace: while this is valid code, I wouldn't recommend it (certainly not for production code). The problem is that if more code is added you'll have a statement that is neither terminated by a brace nor a semicolon.

    The same applies to arrays (and hashes) and commas. Consider this contrived example:

    my @numbers = ( 'one', 'three', 'two' );

    Oops! I'll just reorder those (a simple ddp sequence in vi):

    my @numbers = ( 'one', 'two' 'three', );

    Now you've got an even bigger "Oops!".

    Having said that, the biggest, single improvement you could make to this code would be the use of consistent indentation. It took me some time, tracking back and forth between opening and closing braces, to see where the related blocks of code were. This type of code is highly error-prone. Perhaps look at perlstyle; and perltidy may prove useful.

    — Ken

      > The problem is that if more code is added you'll have a statement that is neither terminated by a brace nor a semicolon

      In fact, in my own code, I never put a semicolon after return: Adding code after

      return $winner;
      makes no sense, as that code wouldn't be reachable. So I'm glad I'll get some kind of a syntax error.

      ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

        I agree, code after a return is unreachable.

        The last sentence of that first paragraph ("The problem is ...") should really have been on a new paragraph; and it should have indicated a general case, rather than the specific case with return. I recall that being my thought process at the time, but clearly it didn't make it to my fingers whilst typing.

        Having said that, I would still recommend adding the semicolon. It clearly indicates where the statement was intended to end. Had an interruption occurred whilst coding, perhaps return was meant to be one of:

        return; return $var;

        Or return $var was meant to be one of:

        return $var; return $var if $condition;

        It's even possible there were meant to be more lines after return $var:

        return $var ? 'TRUE' : 'FALSE';

        — Ken

        In fact, in my own code, I never put a semicolon after return

        Interesting, and thanks all for comments. I do try to work through the source posted, and this might be my final version of highest_number for this thread. I finally worked out what the glitch was in getting the next number after 9. Abridged output, then source:

        $ ./2.cw1.pl ... object created, back with caller word is 2.cw dir2 is perlmonks 2.cw1.html 2.cw2.html ... 2.cw9.html 2.cw10.html 2.cw11.html ... matching is 2.cw9.html matching is 2.cw10.html matching is 2.cw11.html old num is 11 Make rus captions(y/n)?: n ... Put file to server(y/n)?: y server dir is perlmonks ... return is 2.cw12.html
        sub highest_number { use 5.011; my ( $aref, $filetype, $word ) = @_; my $number; my @matching; my $ext = "." . $filetype; push( @matching, 0 ); #min returned value for my $file ( @{$aref} ) { #print "file is $file\n"; if ( $file =~ /^$word(\d+)$ext$/ ) { print "matching is $file\n"; push( @matching, $1 ); } } @matching = sort { $a <=> $b } @matching; my $winner = pop @matching; return $winner }

        I hadn't been sorting numerically. The existence of this page shows that the code works: resulting page.

        What's funny is that I presented with an algorithm I was embarrassed to show, but with the mere addition of { $a <=> $b } and falling back to not having a semi-colon after the return, then I think this is pretty good, lexical perl.

      It also makes nicer diffs when adding lines to the list. You see a line being added instead of a line being changed up top of a line being added.