7

I'm learning the intermediate perl.In that now I'm studying about the object references for class.In that they gave one package

{
    package Barn;

    sub new { bless [], shift }

    sub add { push @{ +shift }, shift }

    sub contents { @{ +shift } }

    sub DESTROY {
        my $self = shift;
        print "$self is being destroyed...\n";
        for ( $self->contents ) {
            print ' ', $_->name, " goes homeless.\n";
        }
    }
}

in this I can't understand the work of plus sign with shift operator. In text they said ,the plus sign is like bareword it would be interpreted as a soft reference: @{"shift"}

can you anybody clearly explain its work for using plus sign with shift operator?

Miller
  • 34,962
  • 4
  • 39
  • 60

1 Answers1

15

Without the plus sign, @{shift} is the same as the array @shift which doesn't call the shift operator at all. Adding the plus sign forces shift to be evaluated as an expression, so the shift operator is called

I would prefer to see @{ shift() }

Methods are normally written so that they extract the first parameter to $self, like this

sub new {
    my $class = shift;
    bless [ ], $class;
}

sub add {
    my $self = shift;
    push @$self, shift;
}

sub contents {
    my $self = shift;
    return @$self;
}
Borodin
  • 126,100
  • 9
  • 70
  • 144
  • 1
    So ,is the plus sign will prevent us from treat the shift operator as @shift array ? – b.sabarathinam saba Jul 13 '16 at 12:49
  • 1
    @b.sabarathinamsaba: That's correct. It turns it into an expression instead of a string, so the `shift` operator is called and its return value is used – Borodin Jul 13 '16 at 12:51
  • What would happen if you replaced the plus with a minus? For example: `perl -E 'sub t { push @{+shift}, 3} @a = 1..2; t(\@a); say join ",", @a'` gives `1,2,3`, whereas if you replace `+shift` with `-shift` you get `1,2`.. – Håkon Hægland Jul 13 '16 at 19:20
  • 1
    @HåkonHægland: I'm not sure that's a useful question. Monadic `+` is pretty much a no-op for scalar operands, but monadic `-` will do unintelligent things to references. (Try `perl -E 'say -[]'`.) While `-'xx'` is simply `-xx`. If you consider every operator as a separately-written function that may behave differently according to whether it is called in list, scalar, or void context then you would be about right. If the behavour isn't documented then experiment, but esoteric uses of operators like `@{+shift}` are ***very wrong*** in my book, precisely because they produce questions like this – Borodin Jul 13 '16 at 19:41
  • @HåkonHægland: None of this is documented behaviour and so shouldn't be used. If you want to understand the internals of Perl then you should become familiar with the C source – Borodin Jul 13 '16 at 19:48
  • 1
    @HåkonHægland: I can't discourage you enough from using whatever functionality you've found. The gems of the internals are all in the C source, meanwhile you should keep writing good, documented Perl solutions. – Borodin Jul 13 '16 at 19:54
  • 1
    More accurately the `+` prevents `shift` from being a *bareword*. – Brad Gilbert Jul 15 '16 at 00:10
  • @BradGilbert: I don't think that's more accurate than what I've written. A bareword is just an unquoted string – Borodin Jul 15 '16 at 01:00
  • 1
    Yes, and adding a `+` causes the parser to treat it differently, and the rest of what you posted happens as a consequence. What you posted almost makes it seem as if it was bug or something. – Brad Gilbert Jul 16 '16 at 14:24