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

@a=(1,2,3,4); push1(\@a,5); print @a; sub push1{ $ref =shift; @a = @$ref; $s=shift; $len=scalar @a; $a[$len] =$s; return \@a; }
The above code . i am writing push function. I passed @a as a reference and i add 5 at end of the array. i print @a in main program. because i am passing reference. Then In actual push statement(push(@a,5)),without using reference,how its work?

Replies are listed 'Best First'.
Re: technique of push
by ikegami (Patriarch) on Sep 02, 2009 at 07:07 UTC

    Operators define their own parsing rules. Some of these can be approximated using prototypes.

    sub my_push(\@@) { my $ref = shift; push @$ref, @_; return 0+@$ref; } my @a = (1..4); my_push(@a, 5); print "@a\n"; # 1 2 3 4 5
      could you explain what is "my_push(\@@)" and "return 0+ @$ref"

        I said it was a prototype. You could have searched the docs for "prototype" :-( They're documented in perlsub.

        As for 0+@$ref, it adds zero to the value to which @$ref evaluates. Keep in mind that the addition operator imposes a scalar context on its operands. perldata says "If you evaluate an array in scalar context, it returns the length of the array." Zero plus the length of the array is the length of the array.

        Since push returns the length of the resulting array, I made my_push return the same thing.

        (Without the 0+, @$ref would be evaluated in the same context as the my_push call, and could result in the wrong value being returned.)

Re: technique of push
by Utilitarian (Vicar) on Sep 02, 2009 at 07:54 UTC
    Through the abuse of the package variable @a your routine works after a fashion, however if you Use strict warnings and diagnostics or die it fails. Consider
    #!/usr/bin/perl use strict; use warnings; sub push1{ my $ref=shift; my @a=@{$ref}; my $s=shift; my $len=@a; $a[$len]=$s; return \@a; } sub push2{ my $ref=shift; my $s=shift; my $len=@{$ref}; $ref->[$len]=$s; return ; } my @a=qw( 1 2 3 4 ); push1(\@a,5); print "Using push1 ", @a,"\n"; @a=qw( 1 2 3 4 ); push2(\@a,5); print "Using push2 ", @a,"\n"; Using push1 1234 Using push2 12345
    You either need to do something with the return value or act on a reference to the array rather than a copy of it.