in reply to Re: CGI problem: USING THE FUNCTION-ORIENTED INTERFACE
in thread CGI problem: USING THE FUNCTION-ORIENTED INTERFACE

That is all correct, but it doesn't actually address how to solve the stated problem. The presented problem appears to me to likely be about getting a single parameter but in a place where you are using a list context. It is unfortunate that the recent CGI changes didn't actually bother to address this problem. We should add a single_param() or one_param() or such method that always returns a single scalar even when called in a list context (and that value is the last value for the named parameter if multiple values were specified for the parameter).

To suppress the warning, you need to use something like:

..., scalar param($name), ...

Note that this gives you the first value and it would make more sense, IMHO, to get the last value instead. You could easily make that choice explicitly with something like:

... ( multi_param($name) )[0] ... # First value ... ( multi_param($name) )[-1] ... # Last value

Except that Perl doesn't get this expression right, IMHO. The above two expressions actually have exactly the same problem as originally motivated the recent changes to CGI.pm. Those expressions that explicitly ask for a single scalar value but Perl allows them to return you other than a single scalar value.

Specifically, ( get_list() )[$index] can (unfortunately) return an empty list instead of a single scalar. It does this when get_list() returns an empty list. In this case, it should instead return undef().

Yes, I understand the motivation for this behavior. It is meant to allow writing code similar to:

my( $one, $two ); while( ( $One, $two ) = ( get_list() )[0,3] ) { # Loops until get_list() returns an empty list. }

(I know this because Larry and I talked about it in the chatterbox years ago.)

But applying that motivation to the case of using a single index in the list slice is pretty darn convoluted:

my $scalar; while( ( $scalar ) = ( get_list() )[0] ) { ... }

I actually think that the original use case I presented is rather convoluted and would much rather have ( get_list() )[$i,$j] always return a list of size 2 (just like happens when using an array slice instead of a list slice).

But I find it especially unfortunate that a list slice with a single index isn't safe to use in a scalar context without jumping through extra hoops.

- tye        

Replies are listed 'Best First'.
Re^3: CGI problem: USING THE FUNCTION-ORIENTED INTERFACE (empty)
by leej (Monk) on Nov 19, 2015 at 06:47 UTC

    It is unfortunate that the recent CGI changes didn't actually bother to address this problem.

    Patches welcome.

    To the original poster - you're referring to out of date documentation. Rule one (perhaps two) with perl - look at the latest documentation, because there's a lot of old, outdated, and bad advice out there. Latest CGI.pm docs are here

      Patches welcome.

      Already submitted a patch to CGI.pm. Already had it rejected.

      The suggestion is spelled out quite clearly above and is nearly trivial to implement. If the maintainers like the idea, then they can implement it about as easily as they can review a patch request (and implement exactly to their taste rather than look at a patch that doesn't quite fit their taste). If they don't like the idea, then a patch request would just be a waste of my time and theirs.

      - tye        

        Already submitted a patch to CGI.pm. Already had it rejected.

        Can you point this out to me please and i shall look at it (possibly again if it was i who rejected it originally).

      Thanks for your kindly reply. I find the old document by searching 'cpan cgi' keyword via google, which is listed on the top and make troubles. In the future, I will search via CPAN first, and then google.
Re^3: CGI problem: USING THE FUNCTION-ORIENTED INTERFACE (empty)
by PhillipHuang (Beadle) on Nov 19, 2015 at 01:10 UTC
    Thank you ,stevieb and tye. As your suggestions, use multi_param() or scalar param() fix it, there's no warning printed. I would raise a bug report at CPAN, and suggest to modify the example code which makes the reader confused(Since the example returns list context, it should not use 'param()').
    "Your name is ",em(scalar param('name')),p,
    or
    "Your name is ",em(multi_param('name')),p,