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

I'm completely mystified by this.

In the 3 example code blocks below I'm pushing the same things onto an array.

When I push the result of a failed match, nothing is pushed onto the array (unless I first save the result in a variable).

Why is this?!

Thanks!

use strict; use warnings; my @foo; push @foo, 1; print scalar @foo, "\n"; # output +: 1 push @foo, 'abc' =~ /abc/; print scalar @foo, "\n"; # output +: 2 push @foo, 'abc' =~ /abcd/; print scalar @foo, "\n"; # output +: 2 - nothing added to @foo?! push @foo, ''; print scalar @foo, "\n"; # output +: 3 push @foo, 0; print scalar @foo, "\n"; # output +: 4 push @foo, undef; print scalar @foo, "\n"; # output +: 5 @foo = (); print "\n"; push @foo, (1); print scalar @foo, "\n"; # output +: 1 push @foo, ('abc' =~ /abc/); print scalar @foo, "\n"; # output +: 2 push @foo, ('abc' =~ /abcd/); print scalar @foo, "\n"; # output +: 2 - nothing added to @foo?! push @foo, (''); print scalar @foo, "\n"; # output +: 3 push @foo, (0); print scalar @foo, "\n"; # output +: 4 push @foo, (undef); print scalar @foo, "\n"; # output +: 5 @foo = (); my $bar; print "\n"; $bar = 1; push @foo, $bar; print scalar @foo, "\n"; + # output: 1 $bar = 'abc' =~ /abc/; push @foo, $bar; print scalar @foo, "\n"; + # output: 2 $bar = 'abc' =~ /abcd/; push @foo, $bar; print scalar @foo, "\n"; + # output: 3 - this time its been added to @foo $bar = ''; push @foo, $bar; print scalar @foo, "\n"; + # output: 4 $bar = 0; push @foo, $bar; print scalar @foo, "\n"; + # output: 5 $bar = undef; push @foo, $bar; print scalar @foo, "\n"; + # output: 6

Replies are listed 'Best First'.
Re: Result of failed regexp match not pushed onto array
by haukex (Archbishop) on Feb 16, 2019 at 12:26 UTC

    This is about scalar vs. list context. A failed match (in this case, 'abc' =~ /abcd/) returns the empty list in list context, which is why push @foo, ('abc' =~ /abcd/);, which takes its arguments in list context, pushes nothing onto @foo. On the other hand $bar = ('abc' =~ /abcd/); causes evaluation of the match in scalar context (because the thing on the left-hand side of the assignment operator is a plain scalar), which means that $bar is assigned Perl's special false value, and then that gets pushed onto @foo.

    Update: If you want to always push a scalar onto the list, you could say push @foo, scalar('abc' =~ /abcd/);.

    Update 2019-08-17: Updated the link to "Truth and Falsehood".

Re: Result of failed regexp match not pushed onto array
by AnomalousMonk (Archbishop) on Feb 16, 2019 at 19:50 UTC

    It's often useful to see what's actually in a structure like an array or hash:

    c:\@Work\Perl\monks>perl -wMstrict -le "use Data::Dump qw(pp); ;; my @foo; my $bar; ;; $bar = 42; push @foo, $bar; print 'A: ', pp(@foo); $bar = 'abc' =~ /abc/; push @foo, $bar; print 'B: ', pp(@foo); $bar = 'abc' =~ /abcd/; push @foo, $bar; print 'C: ', pp(@foo); $bar = ''; push @foo, $bar; print 'D: ', pp(@foo); $bar = 0; push @foo, $bar; print 'E: ', pp(@foo); $bar = undef; push @foo, $bar; print 'F: ', pp(@foo); push @foo, (); print 'G: ', pp(@foo); " A: 42 B: (42, 1) C: (42, 1, "") D: (42, 1, "", "") E: (42, 1, "", "", 0) F: (42, 1, "", "", 0, undef) G: (42, 1, "", "", 0, undef)
    See Data::Dump, which is not core, or Data::Dumper, which is.


    Give a man a fish:  <%-{-{-{-<

Re: Result of failed regexp match not pushed onto array
by zork42 (Monk) on Feb 20, 2019 at 11:46 UTC
    Many thanks haukex (those are useful links) & AnomalousMonk !

    I thought that m// always returned a scalar. Doh!