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

my @gr_choices= qw/jpeg jpg png/; # ??? why does this have to be on +a separate line? given ($ext) { when (@gr_choices) { ...
Originally I wrote the qw directly in the when statement. It doesn't work. Breaking it out like this makes it work as intended. What is the difference? --John

Replies are listed 'Best First'.
Re: Smart-search/When question
by toolic (Bishop) on Mar 18, 2011 at 01:39 UTC
    When I run this code with warnings, it doesn't do what I expect, but I do get warnings:
    use warnings; use strict; use 5.10.0; my $ext = 'jpg'; given ($ext) { when (qw/jpeg jpg png/) { print "ok\n"; } default { print "not ok\n"; } }
    Useless use of a constant (jpeg) in void context at Useless use of a constant (jpg) in void context at not ok

    So I used B::Deparse:

    perl -MO=Deparse given.pl Useless use of a constant (jpeg) in void context at Useless use of a constant (jpg) in void context at given.pl syntax OK sub BEGIN { use warnings; use strict 'refs'; require 5.10.0; } use warnings; use strict 'refs'; BEGIN { $^H{'feature_say'} = q(1); $^H{'feature_state'} = q(1); $^H{'feature_switch'} = q(1); } my $ext = 'jpg'; given ($ext) { when ('???', '???', 'png') { print "ok\n"; } default { print "not ok\n"; } }

    That looks strange. So, I read Switch statements, and I saw an example of an array ref in a "when", and this seems to work:

    when ([qw/jpeg jpg png/]) {

    Perhaps a more knowledgeable monk can explain why.

      Good job tracking this down. It sounds like another way that "smart" match is broken.
Re: Smart-search/When question
by BrowserUk (Patriarch) on Mar 18, 2011 at 01:40 UTC

    Because qw// constructs a list not an array.

    When you did this:

    given ($ext) { when (qw/jpeg jpg png/) {

    You should have seen the warning:

    Useless use of a constant in void context at

    You could do it in-line as:

    given ($ext) { when ( @{[ qw/jpeg jpg png/] ]} ) {

    But it's a bit cheesy.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      What's the difference between a list and an array, as far as when is concerned? What's an example of a list used here that is different from the meaning of an array with the same elements?
        What's the difference between a list and an array, as far as when is concerned?

        This is one of the ways that given/when break expectations in that in most cases, the use of an array expression @a generates a list.

        The only other exception to this I can think of is a subroutine with a prototype of (\@) which causes a reference to the array to be passed to the subroutine. I think that's what is happening here, though the documentation leave much to be desired.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Smart-search/When question
by wind (Priest) on Mar 18, 2011 at 02:23 UTC

    Perl perlsyn

    "Another useful shortcut is that, if you use a literal array or hash as the argument to given , it is turned into a reference. So given(@foo) is the same as given(\@foo) , for example."

    Therefore, just use an array reference like already suggested by toolic:

    when ([qw(jpeg jpg png)]) {

    Or use a regex

    when (/^(?:jpeg|jpg|png)$/) {
Re: Smart-search/When question
by Khen1950fx (Canon) on Mar 18, 2011 at 10:17 UTC
    I'm still trying to get used to 5.10, so I tried it:
    #!/usr/bin/perl use feature qw/:5.10 switch say/; my(@gr_choices) = qw/jpeg jpg png/; given($gr_choices[0]) { when('jpeg') { say 'jpeg is one of the choices'; } }