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

Hi, I have several arrays in my script and if I want to execute my script using one array, on the command prompt, I will be executing the script with $ARGV[1] as the array name. I want to check if the tags (enclosed in < and >) are not outside what is mentioned in the array. I have a subroutine to check this as below.

sub validate_tag { my $arr1=$ARGV[1]; while($_ =~ /<(.+?)>/g) { $found=0; for my $x (0..$#arr1) { if($arr1[$x] eq $1){$found++} } if($found < 1){print "Invalid tag $1 found"} } }

$#arr1 is not returning the correct count of elements in the array. Could anyone help me on this?

Replies are listed 'Best First'.
Re: Reading a array
by davorg (Chancellor) on Aug 08, 2008 at 12:02 UTC
      Further to davorq's most apposite observation, even if $_ had been defined, the $_ =~ is redundant since $_ =~ /RE/ and /RE/ are exactly equivalent.

      You might also want to use the standard strictures and warnings.

      I'm guessing something like this might be a little closer to what you want (to check that, for each tag in a list of tags, the tag body can be found in a named array of valid tag names - or some such) ...

      use strict; use warnings; . . sub validate_tag { # Assume tags passed as arg list while("@_" =~ /<(.+?)>/g) { print "Invalid tag $1 found" unless grep /(:?$1)/, @{$ARGV[1]} +; } } . .

      A user level that continues to overstate my experience :-))
Re: Reading a array
by cdarke (Prior) on Aug 08, 2008 at 13:54 UTC
    I will be executing the script with $ARGV[1] as the array name

    Maybe I read this wrong, but are you attemping to use $ARGV[1] as the name of an array variable?
    Because with use strict; you will get
    $ gash.pl dummy jim Global symbol "@arr1" requires explicit package name

    Methinks you need eval for that, so, with trepidation:
    use strict; use warnings; our @fred = qw(The quick brown camel); our @jim = qw(Fee Fie Foe Fum); sub validate_tag { my $arr1; my $cmd = "\$arr1 = \\\@$ARGV[1]"; eval $cmd; print "$arr1->[0]\n"; } validate_tag(); # end of script $ gash.pl dummy jim Fee
    With trepidation because there is (almost) always a better way of doing it than eval.
Re: Reading a array
by jethro (Monsignor) on Aug 08, 2008 at 12:56 UTC

    If $arr1 holds the name of the array, you can step through the array with

    foreach my $x (0..$#{$arr1}) { if($arr1->[$x] eq $1){$found++} }

    IMO loops like this are better written as

    foreach my $x (@$arr1) { if ($x eq $1) {$found++} }

    You might read up on references and their use in References

Re: Reading a array
by swampyankee (Parson) on Aug 08, 2008 at 13:48 UTC

    No; $#arr1 is returning the correct number of elements in the array; it's just not returning the number of elements you expect to be in the array. Where do you populate @arr1?


    Information about American English usage here and here. Floating point issues? Please read this before posting. — emc

      Don't think so. My interpretation of his code and his question is that he wants to use symbolic references: See "I have several arrays in my script" and "with $ARGV[1] as the array *name*". So in $arr1 is the name of the real array and he wants to access that.

        You're quite likely correct; it's just that from the code fragment given by the OP, I couldn't find where his array was being populated. I also tend to think that an event like $#arr1 giving an incorrect value is unlikely; I would expect that $#arr1 is among the Perl features least likely to have any bugginess. My thinking (I'm easily confused by symbolic references, so I'm likely wrong) is that $#arr1 isn't quite the same as scalar(@$arr1)-1.


        Information about American English usage here and here. Floating point issues? Please read this before posting. — emc