in reply to Re^3: enumerating values for slopes
in thread enumerating values for slopes

$ perl slope5.pl Can't use string ("4.3125") as an ARRAY ref while "strict refs" in use + at ../utils1.pm line 39. $ cat slope5.pl #!/usr/bin/perl -w use strict; use 5.010; use Math::Trig; BEGIN { push @INC, ".."; } use utils1; my @AoA; my $aoa_ref = \@AoA; my @vector = (4.3125, 0.4375); push @AoA, @vector; @vector = (4.375, 0.375); push @AoA, @vector; @vector = (4.4375, 0.375); print_aoa($aoa_ref); __END__ $

Thought I would be comparing hypotenuses to heights but can't see why perl doesn't this is ok.

Replies are listed 'Best First'.
Re^5: enumerating values for slopes
by Laurent_R (Canon) on Sep 23, 2014 at 17:36 UTC
    The error occurs in the module, but the coding error is actually located in your calling program. When you do this:
    my @vector = (4.3125, 0.4375); push @AoA, @vector; @vector = (4.375, 0.375); push @AoA, @vector;
    you are not creating an array of arrays (AoA), but a simple array whose 4 elements are:
    (4.3125, 0.4375, 4.375, 0.375)
    You need to push on @AoA a reference to @vector:
    my @vector = (4.3125, 0.4375); push @AoA, \@vector; @vector = (4.375, 0.375); push @AoA, \@vector;
    or build
    directly an array reference:
    push @AoA, [4.3125, 0.4375]; push @AoA, [4.375, 0.375];
    I guess this should solve your issue.

    As I said earlier, you should avoid using the $a and $b variables, they are special variables used among other things for sorting, they behave differently from other variables, and using as you do them might lead to difficult-to-track bugs. You may use $c or $d, if you like, this will not be a problem, but I would personally put a more meaningful name helping comprehension of what they represent.

    Update: As pointed below by farang the first method above for building an AoA is actually buggy. Use the second one. Thanks to farang for picking that.

      You need to push on @AoA a reference to @vector:
      my @vector = (4.3125, 0.4375); push @AoA, \@vector; @vector = (4.375, 0.375); push @AoA, \@vector;
      That way is buggy, though, as the redefinition of @vector will clobber the first pushed array element. This is explained under COMMON MISTAKES in perldsc, "taking a reference to the same memory location repeatedly".

      So both lines above should instead use a square bracket reference.

      push @AoA, [ @vector ];

        You are right, it's a mistake to push references to the same array without declaring it anew. I have been bitten by that a couple of times, I should know better. That's why I am actually almost always using the second method using the [] anonymous array reference constructor.
      $ perl sill2.pl elt 0 0 is 0.4375 elt 0 1 is 4.3125 elt 0 2 is bath-left elt 1 0 is 0.375 elt 1 1 is 4.375 elt 1 2 is bath-middle elt 2 0 is 0.375 elt 2 1 is 4.4375 elt 2 2 is bath-right bath-left has slope 5.82263230478133 bath-middle has slope 4.91710033552881 bath-right has slope 4.84767847916148 $ cat sill2.pl #!/usr/bin/perl -w use strict; use 5.010; use Math::Trig; BEGIN { push @INC, ".."; } use utils1; my @AoA; my $aoa_ref = \@AoA; my $vector_ref = [0.4375, 4.3125, "bath-left"]; push @AoA, $vector_ref; $vector_ref = [0.375, 4.375, "bath-middle"]; push @AoA, $vector_ref; $vector_ref = [0.375,4.4375, "bath-right"]; push @AoA, $vector_ref; print_aoa($aoa_ref); for my $i ( 0 .. $#AoA ) { my $ratio = $AoA[$i][0]/$AoA[$i][1]; my $rad = asin($ratio); my $degrees = rad2deg($rad); my $name = $AoA[$i][2]; say "$name has slope $degrees"; } __END__ $

      This might be the most robust version of this material.

Re^5: enumerating values for slopes
by Laurent_R (Canon) on Sep 23, 2014 at 06:11 UTC
    Your error is in the ../utils1.pm module, but you don't show the code for that module. Difficult to help you in such conditions.
      $ cd .. $ pwd /home/fred/Desktop/root3/pages/sills/template_stuff $ ls aimages config1.pm lime1.css pm4.txt basketball1.css football1.pm mango1.css rebus1.tmpl bathfan1.css football2.pm marvin1.css rebus2.tmpl blue1.css footer_center2.txt math1.pm rebus3.tmpl bom footer_center_begin.txt nibley1.pm rebus4.tmpl bottom1.txt footer_center.txt oibottom.txt rory1.css captions giles1.css oitop.txt ruscaptions ceres1.css hc_input2.txt pears1.css sills1.css code1.tmpl hc_input.txt plum1.css utils1.pm code2.tmpl html1.pm pluto1.css utils1.pm~ code3.tmpl lemon1.css pm1.txt watermelon1.cs +s $ cat utils1.pm package utils1; require Exporter; use config1; our @ISA = qw(Exporter); our @EXPORT = qw( invert_aoa print_hash print_aoa highest_number get_list zip_lists p_tag); sub invert_aoa{ use strict; use warnings; use 5.010; my $a = shift; my @AoA = @$a; my $k = $#AoA; #say "k is $k"; my @BoB; for my $i ( 0 .. $#AoA ) { my $aref = $AoA[$i]; my $x = $#{$aref}; #say "x is $x"; for my $j ( 0 .. $#{$aref} ) { $BoB[$j][$i]= $AoA[$i][$j]; } } my $b = \@BoB; return $b; } sub print_aoa{ use strict; use warnings; use 5.010; 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; } 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 } sub print_hash{ my $hash_ref = shift; print "subroutine says this is your hash: \n"; my %hash = %$hash_ref; while ( (my $key,my $value) = each %hash ) { print "key: $key, value: $hash{$key}\n"; } } sub get_list{ use strict; use warnings; use 5.010; use File::Slurp; my $file = shift; my @lines = read_file($file); chomp(@lines); s/^\s+|\s+$//g for @lines; @lines = grep length, @lines; return @lines; } sub zip_lists { use strict; use warnings; use 5.010; use List::MoreUtils qw( zip ); my ($file1, $file2) = @_; my @file1lines = get_list($file1); my @file2lines = get_list($file2); say "keys are @file1lines"; say "values are @file2lines"; my %hash = zip @file1lines, @file2lines; return \%hash; } sub p_tag { use strict; use warnings; my $text = shift; my $before = '<p>'; my $after = '</p>'; my $return = $before.$text.$after; return \$return; } 1; $
Re^5: enumerating values for slopes
by Aldebaran (Curate) on Sep 23, 2014 at 06:40 UTC

    What I found when field measuring was that it was much more attainable to get hypotenuses and heights, so that left me looking for arcsin. I had hoped to get this processed as an AoA, but I'm not quite there yet....

    $ perl slope8.pl bath-left theta is 5.82263230478133 bath-middle theta is 4.91710033552881 bath-right theta is 4.84767847916148 dining-south theta is 15.2575232904564 john-north theta is 16.0133944239485 middle-front theta is 24.6243183521641 south-front theta is 14.4775121859299 $ cat slope8.pl #!/usr/bin/perl -w use strict; use 5.010; use Math::Trig; BEGIN { push @INC, ".."; } use utils1; my @AoA; my $aoa_ref = \@AoA; my $tja = 0.4375/4.3125; say "bath-left"; my $hja = asin $tja; my $degrees = rad2deg($hja); say "theta is $degrees"; $tja = 0.375/4.375; $hja = asin $tja; say "bath-middle"; $degrees = rad2deg($hja); say "theta is $degrees"; say "bath-right"; $tja = 0.375/4.4375; $hja = asin $tja; $degrees = rad2deg($hja); say "theta is $degrees"; say "dining-south"; $tja = 1.25/4.75; $hja = asin $tja; $degrees = rad2deg($hja); say "theta is $degrees"; say "john-north"; $tja = 1.0/3.625; $hja = asin $tja; $degrees = rad2deg($hja); say "theta is $degrees"; say "middle-front"; $tja = 1.875/4.5; $hja = asin $tja; $degrees = rad2deg($hja); say "theta is $degrees"; say "south-front"; $tja = 1.125/4.5; $hja = asin $tja; $degrees = rad2deg($hja); say "theta is $degrees"; __END__ $