#!/usr/bin/perl

use 5.038.2;

unless (@ARGV){
    say "\nUsage: $0 <scriptperl1> <scriptperl2> ...";
    say "";
    say "This script count scalar and list uses in a script";
    say "and reports only one use of var name.";
    say "";
    say "Version 2 list subs, scalars, lists and hashes";
    say "and quantity of uses of words in scripts";
    say "";
    say "(!c) Jesús Lozano Mosterín, 2026\n";
    exit -1;
}

for my $arg ( @ARGV ){
    next unless (-e $arg && -T $arg && -s $arg > 10);                              # 10 bytes mínimo
    
    say "filename $arg:";
    
    my @content;
    open my $in, '<', $arg or warn $arg . $!;
    @content = <$in>;
    close $in;
    chomp @content;
    if ( $content[0] =~ /perl/ ) {
	say "Possible error: not a she bang perl line (first line)\n";
    }elsif ($content[0] =~ /\#\!/) {
	say "Possible error: she bang line but not perl invoqued\n";      # possible shell script
	next;
    }else{
	# normal perl, not autovivified
    }
    
    my $linecount = 0;
    my %type;                 # tipo de elemento
    my %hash;                 # tipo de nombre (variable, p.ej.) y ocurrencia
    my $count = 0;
    for my $line ( @content ){
	$linecount++;
	
	while ( $line =~ s/( [ \$ | \@ | \% ] )?([A-Za-z0-9]+)\s*([ \[ | \{ ])?( \( )?//x ) {    # doy por supuesto que cuando tengo $ o @ o % la cosa está hecha. No.
	    #                        1                2                 3         4
	    my $previo = $1;    # opt
	    my $var = $2;
	    my $postvar = $3;
	    my $postsub = $4;
            # Pueden estar en strings o regex, o usarse otra vez pero sólo para asignar algo y no usarlo. Falso negativo.
	    last unless (defined $previo && defined $var && length($var) >= 1);	# noopt    
	    $type{$var} //= "scalar";
	    if ( defined $postvar ){ 
		if ( $postvar =~ /\[/ ){
		    $type{$var} //= "list";
		}elsif ( $postvar =~ /\{/ ){
		    $type{$var} //= "hash";
		}else{
		    $type{$var} //= "unknown";
		}
	    }elsif ( !defined $previo && defined $var && !defined $postvar && defined $postsub ){		    
		$type{$var} //= "sub";
	    }else{
		$type{$var} //= "constant?";
	    }
	    $hash{$type{$var}} = ++$count if defined $type{$var};
	}		
    }
    
    my $flag = 0;
    say "After inspecting $linecount lines of $arg, saw this:";
    for my $i ( sort keys %hash ){
	for my $j ( sort keys %type ){
	    if ($i eq $type{$j}){
		say "\t\t$j is type $i of keyword, with\t\t $hash{$i} ocurrences\t\t ", 'x' x $hash{$i};  
		$flag = 1 if $hash{$i} <= 1;
	    }
	}
    }    
    
    say "\nCongrats! you score 0 in unused variables!" if ($flag == 0);    
    say "$arg inspected by $0 at ", scalar(localtime()), "\n";
}

exit 3;
    
__END__
  
Errores: una variable escondida en un comentario, igual no está escondida :-)

