in reply to Re^3: locating ultima thule
in thread locating ultima thule

show the output here

I did figure out what is going wrong, but I don't know how to fix it. Let me start by showing the tail end of the page creation process, where this thing is going off the rails:

first value is /home/bob/2.scripts/pages/3.cw/template_stuff/aimages Use of uninitialized value in concatenation (.) or string at template_ +stuff/html7.pm line 127, <STDIN> line 2. array part is undefined!...initializing: a is /home/bob/2.scripts/pages/3.cw/template_stuff/aimages/quux b is quux AoA put failed first value is /home/bob/2.scripts/pages/3.cw/template_stuff/aimages Use of uninitialized value in concatenation (.) or string at template_ +stuff/html7.pm line 127, <STDIN> line 2. array part is undefined!...initializing: a is /home/bob/2.scripts/pages/3.cw/template_stuff/aimages/quux b is quux AoA put failed return is 3.cw15.html $

The offenders are create_page and put_page, who until recently, were part of main. Relegating them to be subroutines was great for legibility in main, but I seem to have developed issues. First of all, even though it tells me it fails every time, it gets a page on the net. The resulting page is weirdly-populated. ugly page

sub create_page { use 5.011; use trans1; use Net::SFTP::Foreign; use Encode; use open OUT => ':encoding(UTF-8)', ':std'; #create html page my $rvars = shift; my %vars = %$rvars; my $sftp = get_tiny(); say "object created, back with caller"; my $html_file = get_html_filename( $sftp, $rvars ); $vars{html_file} = $html_file; print "Make rus captions(y/n)?: "; my $prompt1 = <STDIN>; chomp $prompt1; if ( $prompt1 eq ( "y" | "Y" ) ) { my $ref_cap = make_russian_captions($rvars); } my $fh = create_html_file($html_file); my $remote_dir = $html_file; $remote_dir =~ s/\.html$//; say "remote_dir is $remote_dir"; $vars{remote_dir} = $remote_dir; $rvars = \%vars; ## why so necessary? # create header my $rhdr = write_header($rvars); print $fh $$rhdr; $vars{refc} = get_content($rvars); $rvars = \%vars; ## will same trick work? my $body = write_body( $rvars, $vars{refc} ); print $fh $$body; my $rftr = write_footer($rvars); print $fh $$rftr; if ( $vars{"print_script"} ) { my $script = write_script($rvars); print $fh $$script; } if ( $vars{"print_module"} ) { my $module = write_module($rvars); print $fh $$module; } my $rhbt = write_bottom($rvars); print $fh $$rhbt; close $fh; print "Put file to server(y/n)?: "; my $prompt2 = <STDIN>; chomp $prompt2; if ( $prompt2 eq ( "y" | "Y" ) ) { put_page( $sftp, $rvars ); } return $html_file; } sub put_page { use 5.011; #use html6; #use nibley1; use utils1; use Net::SFTP::Foreign; use Encode; use open OUT => ':encoding(UTF-8)', ':std'; use Data::Dumper; my ( $sftp, $rvars ) = (@_); my %vars = %$rvars; #load html file to server my $server_dir = $vars{"server_dir"}; say "server dir is $server_dir"; $sftp->mkdir("/$server_dir") or warn "mkdir1 failed $!\n"; $sftp->setcwd("/$server_dir") or warn "setcwd1 failed $!\n"; $sftp->put( $vars{html_file} ) or die "html put failed $!\n"; #load css file to server $sftp->setcwd("/css") or warn "setcwd2 failed $@\n"; my $path3 = path( $vars{css_path}, $vars{"css_file"} ); say "path3 is $path3"; my $remote_css = $vars{"css_file"}; $sftp->put( "$path3", $remote_css ) or warn "css put failed $@\n"; # upload images my $image_dir = $vars{"image_dir"}; $sftp->mkdir("/$image_dir") or warn "mkdir2 failed $!\n"; $sftp->setcwd("/$image_dir") or warn "setcwd2 failed $!\n"; $sftp->mkdir( $vars{remote_dir} ) or warn "mkdir3 failed $!\n"; $sftp->setcwd( $vars{remote_dir} ) or warn "setcwd3 failed $!\n"; print $sftp->cwd(), "\n"; #print Dumper $rvars; my $ref_content = $vars{refc}; my @AoA = @$ref_content; say "content----------"; print Dumper $ref_content; for my $i ( 0 .. $#AoA ) { say "first value is $vars{to_images} "; say "array part is $AoA[$i][0]"; if (!defined $AoA[$i][0]) { say "undefined!...initializing:"; $AoA[$i][0] = 'quux'; } my $a = path( $vars{to_images}, $AoA[$i][0] ); say "a is $a"; my $b = $a->basename; say "b is $b"; $sftp->put( $a, $b ) or warn "AoA put failed $@\n"; } undef $sftp; return "nothing"; }

My main data struture is a hash that I pass into all my subroutines:

my $rvars = shift; my %vars = %$rvars;

But then I want to create something with persistence, like:

$vars{refc} = get_content($rvars); $rvars = \%vars; ## will same trick work?

and then

print "Put file to server(y/n)?: "; my $prompt2 = <STDIN>; chomp $prompt2; if ( $prompt2 eq ( "y" | "Y" ) ) { put_page( $sftp, $rvars ); }

$ref_content's value is NULL, so this is not an effective pass.

my $ref_content = $vars{refc}; my @AoA = @$ref_content; say "content----------"; print Dumper $ref_content; for my $i ( 0 .. $#AoA ) { say "first value is $vars{to_images} "; say "array part is $AoA[$i][0]"; if (!defined $AoA[$i][0]) { say "undefined!...initializing:"; $AoA[$i][0] = 'quux'; } my $a = path( $vars{to_images}, $AoA[$i][0] ); say "a is $a"; my $b = $a->basename; say "b is $b"; $sftp->put( $a, $b ) or warn "AoA put failed $@\n"; }

It didn't always used to be this broken, so I'm happy to entertain suggestions....

Replies are listed 'Best First'.
Re^5: locating ultima thule
by haukex (Archbishop) on Jan 06, 2019 at 09:43 UTC

    Ok, you've confirmed that $vars{refc}[$i][0] is undef, but as I said, please use Data::Dumper (or Data::Dump) to show the contents of $vars{refc}. Probably the data structure that get_content is returning doesn't match what you're doing with it in put_page.

      please use Data::Dumper (or Data::Dump) to show the contents of $vars{refc}

      What it showed was that the content was populated. What was causing the entire template to go wonky was that there were more files in rus_captions than in eng_captions or images. I filled undefined things with bubble gum and just got them on the net. Most of the complaining is about not being able to sftp non-existent files. I wanted to come up with some baseline defaults so that the whole page doesn't go down for lack of an image to stand in for a while.

      I've gotten rid of a lot of mistakes as I dug my way back into this one. The first was not having brackets around my qw in the initialization of the array:

      elt 0 0 is &#1081; elt 0 1 is elt 0 2 is elt 0 3 is &#1083; elt 0 4 is elt 0 5 is elt 0 6 is &#1089; elt 0 7 is elt 0 8 is Can't use string ("&#1086;") as an ARRAY ref while "strict refs" in us +e at template_stuff/utils1.pm line 61. $

      I don't see a way to use Dumper and have that the be cyrillic, because that's what I want to see. I use Dumper for doing anything to get on the scoreboard. (Not such a high price, except that you condemn yourself to read a lot of your own data: uggh)

      I've been trying to write a better print_aoa_utf8 but have only partial success. Partially, my data set needed more conditioning. The hardest thing for me to represent like this is a space.

      in make russian xword------
      elt 0 0 is й
      elt 0 1 is  
      elt 0 2 is  
      elt 0 3 is л
      elt 0 4 is  
      elt 0 5 is  
      elt 0 6 is с
      elt 0 7 is  
      elt 0 8 is  
      elt 1 0 is о
      elt 1 1 is б
      elt 1 2 is л
      elt 1 3 is о
      elt 1 4 is м
      elt 1 5 is о
      elt 1 6 is в
      elt 1 7 is '
      elt 1 8 is '
      elt 1 9 is ш
      elt 2 0 is 1
      elt 2 1 is 2
      elt 2 2 is 3
      elt 2 3 is 4
      elt 2 4 is 5
      elt 2 5 is 6
      elt 2 6 is 7
      elt 2 7 is 8
      elt 2 8 is 9
      return1 is nothing nyet

      What I have is:

      sub print_aoa_utf8 { use warnings; use 5.011; use utf8; # a la François use open OUT => ':encoding(utf8)'; use open ':std'; my $a = shift; my @AoA = @$a; for my $i ( 0 .. $#AoA ) { my $aref = $AoA[$i]; for my $j ( 0 .. $#{$aref} ) { print "elt $i $j is $AoA[$i][$j]\n"; } } return $a; }

      With my difficulties getting any values initialized. I wonder how I might make it a matter of course and think that a toolkit solution would be a reasonable goal, in particular because I want to have a means for considering fonts, and we saw a tk version of trying out different fonts not long ago.

      I had to make sure that all previous russian captions were erased before I went and got more:

      print "Make rus captions(y/n)?: "; my $prompt1 = <STDIN>; chomp $prompt1; if ( $prompt1 eq ( "y" | "Y" ) ) { ## delete existing files foreach my $child ( $vars{rus_captions}->children ) { my $success = $child->remove; say "success deleting was $success"; } my $ref_cap = make_russian_captions($rvars); }

      STDOUT then shows:

      Make rus captions(y/n)?: y success deleting was 1 success deleting was 1 success deleting was 1 success deleting was 1 matching are a.txt b.txt rus_munge is /home/bob/2.scripts/pages/7.cw/template_stuff/translation +s/trans.07-01-2019-16-15-08.txt rus_path is /home/bob/2.scripts/pages/7.cw/template_stuff/ruscaptions/ +a.txt rus_path is /home/bob/2.scripts/pages/7.cw/template_stuff/ruscaptions/ +b.txt

      And I figured all this out by looking at the data as haukex suggested. I've had a nice few days coding that reduces the ugly, but not completely.

      sub make_russian_crossword { use 5.011; use warnings; use POSIX qw(strftime); use Path::Tiny; use Encode; use open OUT => ':encoding(UTF-8)', ':std'; use Data::Dumper; my $rvars = shift; my %vars = %$rvars; my $munge = strftime( "p%d-%m-%Y-%H-%M-%S\.txt", localtime); my $in_path = path( $vars{rus_captions}, $munge )->touchpath; ##Let mother know that you created a file, *verb* a reference: $vars{log_file}=$in_path; $rvars = \%vars; #does this line do anything for me? # open file for writing # my $fh = path($in_path)->openw_utf8; not helping say "in make russian xword------"; my $data = $vars{cw_data}; #print Dumper $data; print_aoa_utf8($data); #print $fh $data; my $a = $data; my @AoA = @$a; for my $i ( 0 .. $#AoA ) { my $aref = $AoA[$i]; for my $j ( 0 .. $#{$aref} ) { "$AoA[$i][$j]"; } print "\n"; } # ->append_utf8(@data); return "nothing nyet" }

      Does the 3rd line here do anything for me or the program?

      ##Let mother know that you created a file, *verb* a reference: $vars{log_file}=$in_path; $rvars = \%vars; #does this line do anything for me?

      What I'm reaching for at the end is a control that will go over the array, which can be seen as a column vector of row vectors. I want to iterate over the columns and print out one row at time, with no spaces and a newline at the end. Fishing for notation as to how to do that. With the output as a series of outputs of row vectors, then I think it will fit in well with the Path::Tiny method call append_utf8(@data). Then we can see how these things look on the net. Right now, it's looking pretty stable: crossword prototype shaping up.

      Again, very grateful for comments,

        I don't see a way to use Dumper and have that the be cyrillic, because that's what I want to see.

        Yes, Data::Dumper and Data::Dump will output escapes instead of Unicode characters. But the reason I asked for output from one of those modules (twice) is because it provides others, like myself, the best information to help debug your code. The debug output you showed does not really allow differentiating between undef, space characters, or empty strings, and also I can't really help you with the Can't use string as an ARRAY ref error because I'd have to guess which data element it's coming from - it's somewhere in @AoA, but I can't see the actual data structure, nor can I run your code on my end to reproduce the error, because of the missing data. The aforementioned modules will output actual valid Perl syntax, which means it can just be copied and pasted into a Perl script to create a runnable example (or you can just provide a runnable example to begin with).

        For debug output for yourself, you could use Data::Printer, as I showed here, as it will print Unicode characters, but if you want others to help debug, please give them the information they ask for. I also suggest you read through Short, Self-Contained, Correct Example.

        use Data::Dump; dd \@AoA; # - or - use Data::Dumper; $Data::Dumper::Useqq=1; print Dumper(\@AoA);
        use Data::Dump 'dd'; dd(\@foo);