http://www.perlmonks.org?node_id=1043537


in reply to wantarray alternative

Isn't first { $_ } @array the same as $array[0]? (except where $array[0] contains a "false" value.)

sub lowercase { return ( wantarray ) ? map { lc } @_ : lc $_[0]; }

Is your intended use of 'first' really just looking for elements that contain some non-false value (because that's what it does)? If so:

return ( wantarray ) ? map { lc } @_ : lc( first { $_ } @_ );

ie, no need to 'lc' the entire @_ if you are only returning one. Find the one you want, 'lc' it, and return that.


Dave

Replies are listed 'Best First'.
Re^2: wantarray alternative
by tqisjim (Beadle) on Jul 10, 2013 at 19:38 UTC

    I'm really struggling to articulate my question. The real question is: If there's only one value in the return list, how can I return that value in scalar context, not the count of 1?.

    sub lowercase { my @out = map { lc } @_ ; return @out == 1 && ! wantarray ? $out[0]: @out ; }

    This code is optimized based on all the answers so far, and doesn't use first either. In fact, I've probably used this construction thousands of times.

    My question is based on 3 assumptions:

    1. As mentioned, I prefer to avoid using placeholder variables.
    2. I find it awkward to refer to 3 forms of a variable in a single statement.
    3. If I've used this construction thousands of times, and so have others, why hasn't someone developed a single operator?

    I assumed that List::Util would include this functionality. That is, if first or some variant could determine and respond to the wantarray context.

    UPDATE (no update)
      > If there's only one value in the return list, how can I return that value in scalar context, not the count of 1?

      just return the list! In scalar context the last element is taken, so if you are only returning "one value in the return list" thats the same.

      It's the scalar of an array(!) which counts.

      UPDATE

      ok not that easy, avoid scalar context and explicitly put the scalar into a list at LHS.

      DB<129> @out=A..C => ("A", "B", "C") DB<130> sub tst { return map{lc} @out } DB<131> @list = tst() => ("a", "b", "c") DB<132> ($scalar) = tst() => "a"

      Though we asked several times you haven't clarified which result you expect in in case of scalar context and longer list!

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        I'm having trouble following the thread on CB.
        sub lowercase { return map { lc } @_ ; } $jim = lowercase( 'Jim' ) ; ## $jim == 1
        Not the first, not the last, just the count, right?
      return @out == 1 && ! wantarray ? $out[0] : @out;

      So if @out has a single element, return '1'. If it contains zero or 2, or more elements, then if "wantarray", return @out, otherwise return the first element.

      I can't imagine using that once, let alone thousands of times. ;)

      Update: Woops, "&&" is higher on the precedence table than "?:" in any language I know of. My mistake.


      Dave

        Oops. Thanks for catching that :)
        return ( @out == 1 && ! wantarray ) ? $out[0] : @out;