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

ive researched about shift, but only found broad answers that were no help, i cant avoid not understanding shift because it pops up everywhere!!

also, my friend pat showed me a sliding window for a long file, to find Xcharacter patterns,( it would look somethin like this) ACGTTGCAAGCTGTAAA, and there are a couple places are confusing me, help me? :) code is below, thanks in advance

sub getXCharacterPatterns{ my $str=shift; #what does shift do here? my $pl=shift; #andd here my $slen=length($str); if ($pl>$slen){ print "ERROR: $pl is greater than $slen"; } my %nu_hash=(); #why is this an empty hash? (is he storing patterns +in a hash?) my $sstr =""; #why is this an empty string? for(my $i=0;$slen>=$i+$pl; $i++) { $sstr=substr($str,$i,$pl); $nu_hash{$sstr}++; } return \%nu_hash; }

i know my question is quite lengthy, but bear with me :-),

Replies are listed 'Best First'.
Re: trouble understanding code, and shift() w.o args
by moritz (Cardinal) on Aug 04, 2011 at 15:16 UTC

    Try perldoc -f shift, or shift:

    If ARRAY is omitted, shifts the @_ array within the lexical scope of subroutines and formats

    perlvar tells you what @_ is:

    Within a subroutine the array @_ contains the parameters passed to that subroutine.

    I also think that all the perl introductions I've read explain this.

Re: trouble understanding code, and shift() w.o args
by jwkrahn (Abbot) on Aug 04, 2011 at 17:49 UTC
    my %nu_hash=(); #why is this an empty hash? (is he storing patterns +in a hash?)

    It is an empty hash because my creates a new empty variable.    Some people feel that assigning an empty list to an already empty variable is a good practice.

    my $sstr =""; #why is this an empty string?

    Actually, this variable is declared in the wrong scope.    It should be:

    for ( my $i = 0; $slen >= $i + $pl; $i++ ) { my $sstr = substr( $str, $i, $pl ); $nu_hash{ $sstr }++; }

    Which would also be better written as:

    for my $i ( 0 .. $slen - $pl ) { my $sstr = substr( $str, $i, $pl ); $nu_hash{ $sstr }++; }
Re: trouble understanding code, and shift() w.o args
by AR (Friar) on Aug 04, 2011 at 15:23 UTC

    Inside the main body of code, shift without an argument defaults to using @ARGV (the command-line arguments to the script). Inside of a subroutine, shift without an argument defaults to using @_ (the arguments passed to the subroutine).

    %nu_hash is counting the occurrences of substrings in the string passed into the subroutine. You can see that code in the following lines:

    $sstr=substr($str,$idx,$pl); $nu_hash{$sstr}++;
Re: trouble understanding code, and shift() w.o args
by GotToBTru (Prior) on Aug 04, 2011 at 15:41 UTC

    Why are those variables (%nu_hash and $sstr) empty? It is good programming practice to initialize variables. That way, you know for sure what value they contain. Both are used shortly after, but you noticed that. Since they are declared within the subroutine, they will disappear after the subroutine returns control to the main program. Your example is a short subroutine, but this is just good practice to get into.

    When this subroutine is used, it probably looks something like this:

    $returned_value = getXCharacterPatterns($var1, $var2);

    Let's say $var1 = 1, $var2 = 2. When the subroutine runs, Perl will create the array @_ = [1,2]. The first shift will take the first element off the array, and return it. $str will now equal 1, and @_ = [2]. The second shift works similarly. $pl = 2 and @_ will now be empty.

      okay this definately helped, :-) but what if i want an additional filepath as one of the arguments in the subroutine? would it be somethin like this?
      $ret_value = getXCharacterPatterns($var1, $var2, $filepath2);
      wow, u have no idea how much that helped, thx a lot

        Yes, that's how you'd add a third argument. You would need to also add a third shift in the subroutine to use it.

        Perl's handling of parameters to subroutines is strange; every other language I have used requires the parameters be listed in the subroutine definition. I have often seen

        sub translate { my ($noun, $verb, $object) = @_; my $german = "$noun $object $verb"; return($german); }

        in order to document what the subroutine expects: 1) three arguments, 2) in the order noun, verb, object. Also, that would be less confusing to a novice Perl programmer because it explicitly names @_, instead of assuming you know about it. Which, of course, now you do.