John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

I wrote something like:
my ($result)= m[pattern(group)] || "default";
and it didn't work. $result was 1, not the contents of $1. I wrote it using ?: instead, and I can think of a few other ways to write it, so I'm not looking for immediate help on this problem.

What I am wonering is exactly what the issue is, and how to get around it, for my own knowledge. I'm supposing that || forces scalar context on its arguments, and using ()'s around things doesn't help. So how would you get the RE evaluated in list context?

—John

Replies are listed 'Best First'.
Re: Did I match or didn't I?
by gbarr (Monk) on Oct 18, 2001 at 00:23 UTC
    I am assuming that you want $result to contain the contents of the ()'s if the pattern matches, but "default" otherwise. Providing the ()'s cannot return "0" or "" then you could use

    my ($result)= (m[pattern(group)])[0] || "default";

    The outer ()'s put the RE into a list context, then we pick off the first element, which will be the contents of the matching parens

Re: Did I match or didn't I? (boo)
by boo_radley (Parson) on Oct 18, 2001 at 00:21 UTC
    DELETED. This code would not only bite you in the butt, but maybe your loved ones as well.
      I don't think that works.... I parse that as:
      ( my ($bar)=($foo=~m/(ello)/) ) or "default";
      which wont work on a failed match.

      -Blake

        Yea, we use || for defaults on the RHS of assignment all the time. E.g. $x= 0||5; print $x; works as expected. The || is done first, and the result of that is what gets assigned. I think he has the meanings of || and or backwards.
Re: Did I match or didn't I?
by tadman (Prior) on Oct 18, 2001 at 02:24 UTC
    My take is that the double-pipe "binary" OR operator is converting your list (the results from the m//) into a scalar, which in this case is 1 for a singular match. The 'or' OR operator does seem to preserve lists in their entirety, not converting them at all.

    So, the fix, as mentioned, is:
    my ($result) = m[pattern(group)] or "default";
    The two OR operators actually behave quite differently, much in the same way that '==' and 'eq' do similar things, but in a different way.

    The ?: trick is also valid:
    my ($result) = m[pattern(group)]? $1 : "default";
    Since in this case, you are evaluating the result of the match explicitly, then returning either $1 or the string. The former, using 'or', is probably the best way to handle this, since ?: is a bit confusing to some.
      re: "The two OR operators actually behave quite differently"

      That is a whole new issue, since perlop says, "It's equivalent to || except for the very low precedence."

      What are the differences? And lets let the doc pumpking know.

      Updated: The precidence is indeed the only difference. The "as previously noted"

      my ($result) = m[pattern(group)] or "default";
      is not correct.
        The only difference between or and || is precedence. || has high precedence; or has low precedence.

          my @list = func_returning_list() || 'default'; This is parsed as my @list = (func_returning_list() || 'default');, which fails because || forces func_returning_list() into scalar context.   my @list = func_returning_list() or 'default'; This is parsed as (my @list = func_returning_list()) or 'default';, which fails because 'default' is not assigned to @list when func_returning_list() returns an empty list.

        Using ?: is the right solution.

        In perl6, the logic operators will allow their context to propagate to both their operands, so the first snippet will work as intended.

Re: Did I match or didn't I?
by Hofmator (Curate) on Oct 18, 2001 at 12:52 UTC
    I'm supposing that || forces scalar context on its arguments

    You are supposing nearly correctly, || forces scalar context on its left argument - btw something which will be changed in Perl6 (see Exegesis 3, under the heading '... and context for all').

    For solving use any of the good suggestions given elsewhere in this thread :)

    -- Hofmator

Re: Did I match or didn't I?
by suaveant (Parson) on Oct 18, 2001 at 00:12 UTC
    Update I am sorry... I read pattern(group) as a hash lookup for some reason... disregard...

    You need capturing parens in order for anything to come out of your match in list context. If there is no capture, the match returns 1, even in list context... (unless it fails, of course :)

                    - Ant
                    - Some of my best work - (1 2 3)