Professional Web Applications Themes

difference between "_" and "shift" - PERL Beginners

Hi all, I'm having a look in to object oriented perl. Can anyone tell me what the difference between _ and shift is? As far as I know there is no difference except "shift" removes the parameter from the _ array so if you were to "shift" all parameters passed to a function nothing would be containted in _ is this correct? I'm asking because I'm a little confused about using it. Why can't I do this: ####################################### sub nickname { my $self = shift; return $self->{NICK}; } ####################################### But I can do this: ####################################### sub nickname { my $self ...

  1. #1

    Default difference between "_" and "shift"

    Hi all, I'm having a look in to object oriented perl. Can anyone tell me
    what the difference between _ and shift is? As far as I know there is no
    difference except "shift" removes the parameter from the _ array so if you
    were to "shift" all parameters passed to a function nothing would be
    containted in _ is this correct?

    I'm asking because I'm a little confused about using it. Why can't I do
    this:

    #######################################
    sub nickname {
    my $self = shift;
    return $self->{NICK};
    }
    #######################################

    But I can do this:

    #######################################
    sub nickname {
    my $self = shift;
    if (_) { $self->{NICK} = shift
    }
    return $self->{NICK};
    }
    #######################################

    __________________________________________________ _______________
    Express yourself with cool new emoticons http://www.msn.co.uk/specials/myemo

    Graeme Guest

  2. #2

    Default Re: difference between "_" and "shift"

    > Hi all, I'm having a look in to object oriented perl. Can anyone tell me 

    One is a variable, one is function/operator ;-)....

    As far as I know there is no 
    if you 

    _ is just a special Perl variable, it so happens that it is what is
    used to store the arguments to a subroutine temporarily (it has other
    uses, see perldoc perlvar). It also happens that the first argument to
    a subroutine acting like a method is always the object/class that the
    method is invoked on. C<shift> is just a function that removes the
    first/top element of an array, any array, in OOP or not.

    This happens to make things very convenient, aka in most methods you
    will want to remove the instance/class from the argument list to get the
    actual argument list back, and shift by itself will default to use _.
    So essentially you are left with some syntactic sugar to make life easier.

    So,

    my $self = shift;

    Just says to grab the instance from _ (by default), store it in $self,
    and restore the arg list to what the user actually passed. You don't
    *have* to do it, but it is very convenient.
     

    No reason you can't. Provided you have already set $self->{NICK} or
    don't mind getting an undefined value.

     

    Only difference here is that you set $self->{NICK} in the event that an
    argument was passed, aka after shift'ing there is still an argument in
    _ (namely the value you want to set NICK to).

    Additional suggested reading:

    perldoc perlboot
    perldoc perltoot
    perldoc perltooc

    http://danconia.org
    Wiggins Guest

  3. #3

    Default Re: difference between "_" and "shift"

    I am (admitedly) unfamiliar with OO Perl. I understand enough to grok
    what you are saying, Wiggins, but I have a question.

    Does a sub (like the one above) have a problem with being called with
    & as opposed to not being called with an & with OO Perl? That
    questions was worded weird. Let me try again. As I understand it, if
    you call a sub with '&subname', the sub's _ variable will share the
    calling scope's _ variable, BUT, if you call the sub with 'subname()'
    it will get it's own, fresh _. is that true? And if it is, does
    this affect the subs being used with OO Perl?

    --Errin
    Errin Guest

  4. #4

    Default Re: difference between "_" and "shift"

    On Thu, 30 Sep 2004, Graeme McLaren wrote:
     

    The former is a variable; the latter is a function.

    _ is one of Perl's "pronoun" variables: just as $_ refers to "that"
    which you were most recently working with, _ refers to "those" which
    you were most recently working with. $_ is a scalar -- "it" or "that"; a
    single thing. _ is a list -- "those" or "these"; a plural thing.

    shift is a function for pulling off the first element from a list. If
    you've ever had to take a data structures class, you may remember that
    two of the main ways to deal with collections of things as as stacks
    (where you only deal with the top, and you can push onto it or pop off
    of it) and queues (where everything moves in a line, and you enqueue
    onto the end and dequeue from the front). Perl has functions that let
    you work with arrays in these ways. You can push to and pop from the end
    of lists to treat them as stacks; you can shift from and unshift to the
    front of lists to, well, also treat them as stacks; and you can push &
    shift or pop & unshift to treat it as forward or reverse queues.

    So. In the context of subroutine arguments, you're generally passing in
    one or more arguments. If you're only passing one, then you're right --

    my $arg = _;
    my $arg = shift;
    my $arg = $_;

    -- are all equivalent. If, on the other hand, you have multiple args,
    then these will all do different things.

    my args = _;

    my $arg[0] = shift;
    my $arg[0] = $_;

    If you pass the wrong thing and aren't ready for it, you can throw away
    incoming data and possibly break things.
     

    Well, yes, in that this will deplete _, but that doesn't mean that
    there is no difference between shift and _ -- they're different things.



    --
    Chris Devers
    Chris Guest

  5. #5

    Default Re: difference between "_" and "shift"

    On Thu, 30 Sep 2004 20:19:11 +0100, Graeme McLaren
    <com> wrote: 

    Straight from "the Llama" :
    array = qw /dino fred barney/;
    $a = $shift array; # $a gets "dino", array reduced to ("fred" , "barney");
     

    _ variable is local to the subroutine. It stores argument to a
    subroutine. If u keep on doing "shift" inside a subroutine then _
    will be empty & will become uninitialized again.
    sub test {
    #$a = shift ;
    my $a = shift _ ;
    print $a;
    my $b = shift _;
    print $b;
    }
    &test(1);
    ->perl -w test.pl
    ->Use of uninitialized value in print at test.pl line 9.
    1

    But this doesn't in anyway affect the _ variable outside the
    subroutine if there happens to be any.
     
    [snip]

    "$self" looks alot like "this" in Java.. no? :)

    --
    Cheers,
    SanoBabu
    Sano Guest

  6. #6

    Default Re: difference between "_" and "shift"

    > I am (admitedly) unfamiliar with OO Perl. I understand enough to grok 

    Solid question, which took some hunting in the docs.... but they are
    solid docs, from perldoc perltoot,

    "From the C++ perspective, all methods in Perl are virtual. This, by
    the way, is why they are never checked for function prototypes in the
    argument list as regular builtin and user-defined functions can be."

    This confirmed my hunch. The C<&> has a number of purposes beyond just
    passing the current _ in recursive like functions, such as
    dereferencing subroutines, etc. See perldoc perlsub for lots about
    subroutines, prototypes, and their behaviours. My hunch was that since
    you invoke a method on an object/class, such as

    My::Class->method();
    or
    $object->method();

    You would have to figure out where to put the sigil,

    &$object->method();

    Would either cause confusion wrt trying to dereference a subroutine, or
    trying to chain a method on the return value of a dereferenced
    subroutine, which would be pretty cool, though not terribly readable. Or,

    $object->&method();

    Which I suspected could work, but had never seen it before (not that I
    am an expert) but it strikes me as something difficult to p.

    Now to the more important part, and the more literal meaning of your
    question, in Perl it doesn't affect anything! Why? because the method,
    when invoked as a regular sub call will run just fine! The danger is
    that you (may) have broken the interface, so if the sub is really a
    method *expecting* the first argument to be an object/class, then it may
    fail to function as doented. This is where the beauty of Perl comes
    in though, why can't you have both! For instance many subs can check
    their first argument to see if it is a reference, in that case it treats
    the call like a method, if the first arg isn't, then it treats it like a
    regular sub call. This is similar to other areas of Perl that function
    based on the *context*. Many modules that provide a functional and OOP
    interface are operating under this principal. So whether or not Perl
    will let you, it will, whether or not you can/should depends on the
    underlying implementation and whether it is doented. Calling what is
    normally a method with C<&> as a regular sub call will pass _
    unmangled, the question becomes does _ already have the object/class
    attached, or is the sub smart enough to recognize that it doesn't.

    http://danconia.org
    Wiggins Guest

  7. #7

    Default Re: difference between "_" and "shift"

    > On Thu, 30 Sep 2004, Graeme McLaren wrote: 
    >[/ref]

    <snip>
     

    DANGER, DANGER.... the above takes a list in scalar context, $arg is now
    '1', not the value of the first argument. Throw in some parens to fix
    that guy....

    my ($arg) = _;
     

    <snip>
     

    http://danconia.org
    Wiggins Guest

  8. #8

    Default Re: difference between "_" and "shift"

    > So. In the context of subroutine arguments, you're generally passing in 
     
    So what wiggins saying, here $arg has now 1 ?
     
    here $arg has now the value of the first element(argument) ?
     
    here $arg gets default value?
     

    I agree. :)

    [snip]
    --
    Cheers,
    SanoBabu
    Sano Guest

  9. #9

    Default Re: difference between "_" and "shift"

    > > So. In the context of subroutine arguments, you're generally passing in 

    > So what wiggins saying, here $arg has now 1 ?
    >[/ref]

    Yes. It is the length of the array, or "a list taken in scalar context".
     
    > here $arg has now the value of the first element(argument) ?

    > here $arg gets default value?[/ref]

    Ha, didn't even notice that one, yep $_ is definitely different than
    $_[0], which is what the others would have.
     
    >
    > I agree. :)
    >[/ref]

    ?? You are agreeing that they are, or aren't? They definitely aren't.
     

    http://danconia.org

    Wiggins Guest

  10. #10

    Default Re: difference between "_" and "shift"

    > Ha, didn't even notice that one, yep $_ is definitely different than 
    > >
    > > I agree. :)
    > >[/ref]
    >
    > ?? You are agreeing that they are, or aren't? They definitely aren't.[/ref]

    hahah..That was a bad post..I mean I agree with what u said. :-)


    [snip]

    --
    Cheers,
    SanoBabu
    Sano Guest

  11. #11

    Default Re: difference between "_" and "shift"

    Chris Devers wrote: 

    Wrong! If you try to use shift() with a list it will print out a nice error
    message "Type of arg 1 to shift must be array".

    perldoc -q "What is the difference between a list and an array"


    John
    --
    use Perl;
    program
    fulfillment
    John Guest

  12. #12

    Default Re: difference between "_" and "shift"

    On Thu, 30 Sep 2004, John W. Krahn wrote:
     
    >
    > Wrong! If you try to use shift() with a list it will print out a nice
    > error message "Type of arg 1 to shift must be array".
    >
    > perldoc -q "What is the difference between a list and an array"[/ref]

    Whoops! I stand corrected. Sorry about that.

    In any case, the bigger point is that _ and shift are much different
    things -- they may be used in similar places, but that doesn't make them
    into synonyms.



    --
    Chris Devers
    Chris Guest

Similar Threads

  1. Replies: 3
    Last Post: February 8th, 05:19 AM
  2. Replies: 1
    Last Post: April 24th, 01:27 PM
  3. CFINPUT type="radio" w/ "value" requires "label"
    By Iceborer in forum Macromedia ColdFusion
    Replies: 2
    Last Post: February 21st, 06:16 PM
  4. "Start" "Program" "Menu" list is empty
    By Pete in forum Windows XP/2000/ME
    Replies: 2
    Last Post: July 10th, 10:42 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139