jcklasseter has asked for the wisdom of the Perl Monks concerning the following question:

So, I'm trying to make a script that will assign input to a variable vector, print, and go to the next line and repeat. Go figure, I'm stuck. Any ideas?
#!/usr/bin/perl use strict; use warnings; use diagnostics; use Math::Vector::Real; my $source = "./IN"; my $out = "./OUT"; open(IN, '<', $source) or die "Couldn't open $source: $!\n"; open(OUT, '>', $out) or die "Couldn't open $out: $!\n"; sub vector { my ($aa) = @_; $aa->[0] = my $one; $aa->[1] = my $two; $aa->[2] = my $three; my $vector = V($one, $two, $three); } my @data = map [ split ], grep /\S/, <IN>; foreach my $d1 (@data) { print OUT " The vector of Atom ($d1->[0], $d1 +->[1], $d1->[2])is : %f\n", vector($d1); } close IN; close OUT;
My Input file is:
0 5 5 1 2 3 3 5 6 2 5 2 5 5 5 5 5 6
And this is the error I get when I run it,
mac95406:perl a7c$ ./perl Use of uninitialized value in join or string at /Library/Perl/5.16/Math/Vector/Real.pm line 219, <IN> line 6 (#1) (W uninitialized) An undefined value was used as if it were alread +y defined. It was interpreted as a "" or a 0, but maybe it was a mi +stake. To suppress this warning assign a defined value to your variables. To help you figure out what was undefined, perl will try to tell y +ou the name of the variable (if any) that was undefined. In some cas +es it cannot do this, so it also tells you what operation you used th +e undefined value in. Note, however, that perl optimizes your progr +am anid the operation displayed in the warning may not necessarily ap +pear literally in your program. For example, "that $foo" is usually optimized into "that " . $foo, and the warning will refer to the concatenation (.) operator, even though there is no . in your program.
The line that the error directs me to is:
sub as_string { "{" . join(", ", @{$_[0]}). "}" }
Even knowing what that error means would be great for starters. Everything I see is declared and should have a value. I'm probably just blind though. Any help is appreciated.

Replies are listed 'Best First'.
Re: How to vector
by AnomalousMonk (Archbishop) on Jun 19, 2015 at 20:08 UTC
    sub vector { my ($aa) = @_; $aa->[0] = my $one; $aa->[1] = my $two; $aa->[2] = my $three; my $vector = V($one, $two, $three); }

    In this function:

    1. The function is passed an array reference;
    2. The first three elements of the referent of this array reference are assigned the initial values (undef) of three newly-created lexical scalars;
    3. The values (all still undef) of these newly-created scalars are passed to the  Math::Vector::Real::V() function;
    4. The return value of the  V() call is assigned to a new lexical scalar  $vector (which immediately goes out of scope) and is also implicitly returned from the function call.
    Does passing the scalar values of  $one $two $three (all undef) to  V() serve any purpose? Given that its argument parameters are always the same, can  V() ever return any differing value; i.e., is it an impure function?

    I haven't examined Math::Vector::Real at all, but I would suspect things begin to go wrong within the  vector() call itself.


    Give a man a fish:  <%-(-(-(-<

      Well, I was trying to have field 0,1,and 2 assigned to one, two, and three. Then have the vector assigned with this values as it's values. How could I change the array reference to each field value?
        How could I change the array reference to each field value?

        As I understand it, the array reference already references each field's value. You need to pass these values to V(). Maybe something like (untested):

        sub vector { my ($aa) = @_; return V(@$aa); }
        Again, I haven't studied the relevant module.

        As you can see, most of the function defined above is irrelevant. Why not just (also untested):

        my $some_scalar = V(@$original_array_reference);
        instead?

        Update: After actually looking at Math::Vector::Real, it seems that  V() returns a blessed reference of some kind (update: you also reference | make note of this below), not a floating point number as implied by the  %f format specifier in the OPed  printf statement. You will have to manipulate this  V object into some form of data usable to you, which I cannot judge.


        Give a man a fish:  <%-(-(-(-<

Re: How to vector
by stevieb (Canon) on Jun 19, 2015 at 20:09 UTC

    I have a feeling your problem may be in this code:

    $aa->[0] = my $one; $aa->[1] = my $two; $aa->[2] = my $three;

    You need to define these variables before assigning them, or you'll get the types of errors you're seeing. Are you sure it shouldn't be written like this instead?:

    sub vector { my ($aa) = @_; my $one = $aa->[0]; my $two = $aa->[1]; my $three = $aa->[2]; my $vector = V($one, $two, $three); }

    -stevieb

    ps. I don't have any experience with that module, so I'm just guessing.

      It got something to print out at all. Positive step. A vector, according to the module, is similar to a blessed array reference. The exact output is
      The vector of Atom (0, 5, 5)is : %f {0, 5, 5} The vector of Atom (1, 2, 3)is : %f {1, 2, 3} The vector of Atom (3, 5, 6)is : %f {3, 5, 6} The vector of Atom (2, 5, 2)is : %f {2, 5, 2} The vector of Atom (5, 5, 5)is : %f {5, 5, 5} The vector of Atom (5, 5, 6)is : %f {5, 5, 6}
      Which is progress.

        The fact that  %f appears in the output stream suggests you are not using a printf (or sprintf) statement, and I don't know where the  {0, 5, 5} bits are coming from. Difficult to comment further.


        Give a man a fish:  <%-(-(-(-<

Re: How to vector
by Laurent_R (Canon) on Jun 19, 2015 at 20:55 UTC
    These code lines:
    $aa->[0] = my $one; $aa->[1] = my $two; $aa->[2] = my $three;
    are obviously wrong, because $one, $two and $three have not been initialized, and also because a my is usually applying on a L-value or left-hand side of an assignment (although there are a few specific cases where it can apply to a R-value). I am not sure of what you are trying to achieve, but it seems likely that you are really trying to do something like:
    my $one = $aa->[0]; # ...
    I am also not sure that you really need Math::Vector::Real for what you intend to do. Using core arrays and possibly arrayrefs should be sufficient.

    Please explain in more details what you are trying to do.

Re: How to vector
by pme (Monsignor) on Jun 19, 2015 at 20:09 UTC
    Hi jcklasseter,

    Do you have any specific reason to use Math::Vector::Real? You can do that with perl arrays and arrayrefs.

    use strict; use warnings; use Data::Dumper; open IN, "<IN" or die "Cannot open IN\n"; my @arr; while (<IN>) { chomp; my @line = split; push @arr, \@line; } close IN; print Dumper(\@arr) . "\n"; foreach (@arr) { print "$_->[0] - $_->[1] - $_->[2]\n"; }
      Eventually it will be used to vector math with. Baby steps right now though, let's see if I can even assign them right. Can Arrays be used similar to vectors for vector math purposes?
        They can't. That's what Math::Vector::Real does, implementing the mathematical vector semantics on top of arrays.

        You posted an example of just that this last week. Unlike hashes, arrays are ordered, so they can fit this bill. A typical Pythagorean triple might be @a = (2,3,7);. There has to be an origin: @o=(0,0,0);. One way this differs from typical mathematical treatments is that the indices begin with zero, but all that requires is that you be consistent. One thing you can't have are strings in your vector so this: @d=(8,7,dog); will never be a vector. Hope this helps.