Under the heading of Stupid (Perl) Things I Did Today, is this Forehead Slapper:
# define option names and defaults our $UNIQUE_OPT = q/unique/; our $FORCE_OPT = q/force/; our $VERBOSE_OPT = q/verbose/; our $OUTPUT_EXT_OPT = q/ext/; # create option specs for Getopt my @option_config = qw( $UNIQUE_OPT $FORCE_OPT $VERBOSE_OPT $OUTPUT_EXT_OPT=s ); # create option hash for Getopt my(%option, %option_config); foreach my $option_config ( @option_config ) { # copy $option_config to $option_name, keep only name of option ( my $option_name = $option_config ) =~ s/\W.*$//; # save a reference to the %option value in %option_config hash $option_config{$option_config} = \$option{$option_name}; } # process options GetOptions %option_config or usage(); if ( $option{$UNIQUE_OPT} and $option{$FORCE_OPT} ) { die "-$UNIQUE_OPT and -$FORCE_OPT are mutually exclusive." . " See $SCRIPT_NAME -help for syntax."; }
This broke with:
C:\>perl myscript stuff Error in option spec: "$VERBOSE_OPT" Error in option spec: "$FORCE_OPT" Error in option spec: "$OUTPUT_EXT_OPT=s" Error in option spec: "$UNIQUE_OPT"
Due to the hour of the day, I sat and stared at this for some time, scanned through Getopt::Long, and scratched my head.

Finally it hit me -- qw doesn't interpolate, so things like $UNIQUE_OPT don't DWIM. The fix was:

my @option_config = split ' ', qq( $UNIQUE_OPT $FORCE_OPT $VERBOSE_OPT $OUTPUT_EXT_OPT=s );
which looks very similar to the rough equivalent of qw as found in perlop:
split(' ', q/STRING/);
In fact, it made me wonder if this DWIM:
my @option_config = qw" $UNIQUE_OPT $FORCE_OPT $VERBOSE_OPT $OUTPUT_EXT_OPT=s ";
:( Sadly, it doesn't.

Anyone care to comment on whether this should or shouldn't make it into the language?

-QM
--
Quantum Mechanics: The dreams stuff is made of

Replies are listed 'Best First'.
Re: qw "$string $string" doesn't interpolate
by bmann (Priest) on Jun 12, 2004 at 00:27 UTC
    I'm curious - why not something like this?
    # note the trailing comma at the very end of the list my @option_config = ( $UNIQUE_OPT, $FORCE_OPT, $VERBOSE_OPT, $OUTPUT_EXT_OPT, );

    As far as making it into the language, I would vote no. I fail to see the benefit. Why quote, interpolate then split into a list when it's no more effort to create a list in the first place?

Re: qw "$string $string" doesn't interpolate
by Juerd (Abbot) on Jun 12, 2004 at 08:12 UTC

    juerd@ouranos:~$ perl -MO=Deparse -e'print qw(a b c)' print 'a', 'b', 'c'; -e syntax OK
    qw is expanded before the code runs. At that time, variables usually have no value yet. Interpolation would mean delaying until runtime, of having very unexpected results. Of course, it could still optimize for the variableless case, but that would mean that qw($foo $bar) is many times slower than qw(foo bar).

    Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

      ++

      So q, qq, qx, and qw aren't captured in the structure that Deparse operates on. You could almost say they were source filters. Which is efficient, but not what I was hoping for.

      So getting qw"$string" to interpolate doesn't look like an oversight, it's a result of the implementation. I can't see a good reason to change it, given there's a work around for my "problem" [laziness], and existing code could break.

      [Makes me wonder how many qw"$string" occurrences there are in existing code?]

      Thanks,

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

        So q, qq, qx, and qw aren't captured in the structure that Deparse operates on.

        That structure is the bytecode. Perl doesn't directly execute your code. It first compiles the thing to bytecode and then executes that in the virtual machine. This all happens transparently. B::Deparse translates (or at least tries to) the bytecode back to readable Perl.

        Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

Re: qw "$string $string" doesn't interpolate
by gmpassos (Priest) on Jun 12, 2004 at 07:28 UTC
    All the q operators means a personalized quote. So, q``, q~~, q//, q{}, q"", q'', are all the same, a personalized quote for ''. (that won't interpolate values)

    Also qq``, qq~~, qq//, qq{}, qq"", qq'' are all the same, a personalized quote for "". (that will interpolate values)

    So, what metters is the q operator, and not the char used to delimite the string.

    Now qw means quote word, and again, qw``, qw{}, qw(), qw"", qw'', are all the same. a personalized quote word, that means: split(/\s+/,'a b c $x $y $z') , where interpolation doesn't exists and there's no place that says that exists interpolation for quote word.

    So, what metters is the operator and not the char used with q, qq, qw, qr...

    http://perldoc.com is your friend!

    Graciliano M. P.
    "Creativity is the expression of the liberty".

      I dunno, there's an obvious conclusion to draw from all this:

      operatoracts oninterpolates
      qstringno
      qqstringyes
      qwwordno
      qqwwordyes

      ... except that the last row in bold doesn't exist. That would be pretty cool actually, there have been times when I would have liked to be able to do just that.

      Oh well, no-one ever claimed that Perl's operators were orthogonal.

      - another intruder with the mooring of the heat of the Perl

        I was just about to post the same question, and I see the question has already been asked.

        qqw needs to be part of the core, IMHO. It would also function (via accidential TIMTOWTDI-ness) as a split on space delimited strings... @tokens = qqw/$foo/;

      gmpasso: Yes, all of your points are well made, but speak to the existing condition (including the [perdoc://] reference).

      What I want to discuss is Why?

      [And can I get my own personalized q* operators? That would be cool. Maybe qm(), for QM? ;^)]

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

        What I want to discuss is Why?
        For me, this is one of the most annoying questions that get asked about the way things work in perl. You can ask it about ANYTHING, and the answers is alway one of:
        • Because Larry wanted it so
        • Because some patch by the perl5-porters made it so
        • Its a bug (doesn't apply if its documented -- documented bugs are features)
        • It doesn't matter why, that's the way it works, there is nothing to discuss :)
        [And can I get my own personalized q* operators? That would be cool. Maybe qm(), for QM? ;^)]
        Sure, why not? If you're talking about perl5, you need to use filters of course. If you're talking perl6, you'll have to check http://perl6.org (i don't recall off the top of my head).

        MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
        I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
        ** The third rule of perl club is a statement of fact: pod is sexy.

        A reply falls below the community's threshold of quality. You may see it by logging in.
Re: qw "$string $string" doesn't interpolate
by revdiablo (Prior) on Jun 12, 2004 at 00:26 UTC

    I don't know why they chose to make qw not interpolate, but just for kicks, you could cause interpolation in qw with something like:

    my @option_config = map eval qq("$_"), qw( $UNIQUE_OPT $FORCE_OPT $VERBOSE_OPT $OUTPUT_EXT_OPT=s );
Re: qw "$string $string" doesn't interpolate
by Anonymous Monk on Jun 12, 2004 at 02:32 UTC

    Well, I don't know which came first, but here is something to note:

    qw is commonly used to pass in a list of things to import when using a module that extends Exporter. Most often Exporter is used to allow the import of subs, but can also be used to Export/Import variables. So, if the module Foo allowed the import of %h and $s, I might say:

    use Foo qw/$s %h/;
    

    And, if I really wanted interpolation, I would just use () instead of qw(), as mentioned above.

    But I will agree that qw"" looks like it should interpolate. But, by definition, qw effectively does a split /\s+/ on the string. If qw"" did interpolate, should it split before the interpolation or after? This uncertainty may be why the never implemented interpolation in the first place.

    Ted
Re: qw "$string $string" doesn't interpolate
by PodMaster (Abbot) on Jun 12, 2004 at 07:24 UTC
    In fact, it made me wonder if this DWIM:
    my @option_config = qw" $UNIQUE_OPT
                            $FORCE_OPT
                            $VERBOSE_OPT
                            $OUTPUT_EXT_OPT=s
                          ";
    
    :( Sadly, it doesn't.
    Have you checked to see if
    my @option_config = q" $UNIQUE_OPT $FORCE_OPT $VERBOSE_OPT $OUTPUT_EXT_OPT=s ";
    interpolates? :)

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

      Have you checked to see if
      my @option_config = q" $UNIQUE_OPT $FORCE_OPT $VERBOSE_OPT $OUTPUT_EXT_OPT=s ";
      No, but doing so shows me that @option_config is equivalent to:
      [ ' $UNIQUE_OPT $FORCE_OPT $VERBOSE_OPT $OUTPUT_EXT_OPT=s ' ]
      a single element array, complete with the newlines and leading whitespace. Not DWIM.

      I'm not sure what your point was...Should q"" interpolate or not? I would suggest it should not, because that would be confusing. But I could live with the argument that it should, because then the behavior of double-quotish strings would be consistent.

      On the 3rd hand, things like s"$foo"$bar" behave differently from s'$foo'$bar':

      $foo = 'foo'; $bar = 'bar'; $football = 'football'; ($x = $football) =~ s"$foo"$bar"; # $x eq 'bartball' ($x = $football) =~ s'$foo'$bar'; # $x eq 'football' (no change)
      My point is, qw is not apparently single-quotish in nature, but it would DWIM to have it double-quotish using double quotes, as with other operators.

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

        ...Not DWIM.

        I'm not sure what your point was...Should q"" interpolate or not?

        You need to stop saying DWIM. Of course q"" should not interpolate because that's now how the quoting operators work. The quoting operators allow you to use alternate delimiters so you can get the benefits of ' (no interpolation, q) and " (interpolation, qq) without the need to escape ' and " in the strings.
        On the 3rd hand, things like s"$foo"$bar" behave differently from s'$foo'$bar',... My point is, qw is not apparently single-quotish in nature, but it would DWIM to have it double-quotish using double quotes, as with other operators.
        qw is single-quotish in nature (a quoting operator which doesn't interpolate). s and m are not quoting operators, they are "Regexp Quote-Like Operators".

        MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
        I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
        ** The third rule of perl club is a statement of fact: pod is sexy.