Loading ...
Sorry, an error occurred while loading the content.

Quoting hash keys changes things sometimes

Expand Messages
  • Kelly Jones
    Consider: perl -le $hash{ foo-bar } = 1; print $hash{foo-bar} [no result] perl -le $hash{ foobar } = 1; print $hash{foobar} 1 I sort of understand this: in
    Message 1 of 3 , Nov 15, 2008
    View Source
    • 0 Attachment
      Consider:

      perl -le '$hash{"foo-bar"} = 1; print $hash{foo-bar}'
      [no result]

      perl -le '$hash{"foobar"} = 1; print $hash{foobar}'
      1

      I sort of understand this: in the first script, Perl treats foo-bar as
      a subtraction, and sets $hash{0} to 1. In the second one it assumes
      you just left off some quotes.

      My question: since Perl doesn't have constants, what exactly IS
      foo-bar? Why is it 0?

      The behavior above seems inconsistent to me. Is it considered a bug?

      --
      We're just a Bunch Of Regular Guys, a collective group that's trying
      to understand and assimilate technology. We feel that resistance to
      new ideas and technology is unwise and ultimately futile.
    • Jeff Pinyan
      ... If you had warnings turned on, you d be told that foo and bar are unquoted barewords that are being treated as constants. And strings treated in
      Message 2 of 3 , Nov 15, 2008
      View Source
      • 0 Attachment
        On Sat, Nov 15, 2008 at 1:52 PM, Kelly Jones <kelly.terry.jones@...>wrote:

        >
        > perl -le '$hash{"foo-bar"} = 1; print $hash{foo-bar}'
        > [no result]
        >

        If you had warnings turned on, you'd be told that 'foo' and 'bar' are
        unquoted barewords that are being treated as constants. And strings treated
        in numeric context (which the - operator puts them in) become numbers.
        Strings like '123foo' become 123, but strings like 'foo' become 0.


        > perl -le '$hash{"foobar"} = 1; print $hash{foobar}'
        > 1
        >

        A hash key, if it is comprised SOLELY of letters, digits, and underscores, *
        if* it begins with a letter or underscore, *does not* need to be quoted:

        $hash{abc}
        $hash{a1_b2}
        $hash{_3pennyOPERA}

        Those are all ok. So is $hash{58} for that matter. But $hash{58times} is
        not ok.

        It's not a bug. It's a documented feature in *perldata*:

        In fact, an identifier within such curlies is forced to be a string,
        as
        is any simple identifier within a hash subscript. Neither need quot-
        ing. Our earlier example, $days{'Feb'} can be written as $days{Feb}
        and the quotes will be assumed automatically. But anything more com-
        plicated in the subscript will be interpreted as an expression. This
        means for example that "$version{2.0}++" is equivalent to "$ver-
        sion{2}++", not to "$version{'2.0'}++".

        --
        [Mary said,] "Do whatever he tells you." ~ John 2:5
        The Cross Reference - http://thecrossreference.blogspot.com/
        Nos autem praedicamus Christum crucifixum (1 Cor 1:23)


        [Non-text portions of this message have been removed]
      • Jenda Krynicky
        From: Kelly Jones ... The rule for automatic quoting within $hash{...} is if it looks like word, it doesn t have to be
        Message 3 of 3 , Nov 15, 2008
        View Source
        • 0 Attachment
          From: "Kelly Jones" <kelly.terry.jones@...>
          > Consider:
          >
          > perl -le '$hash{"foo-bar"} = 1; print $hash{foo-bar}'
          > [no result]
          >
          > perl -le '$hash{"foobar"} = 1; print $hash{foobar}'
          > 1
          >
          > I sort of understand this: in the first script, Perl treats foo-bar as
          > a subtraction, and sets $hash{0} to 1. In the second one it assumes
          > you just left off some quotes.

          The rule for automatic quoting within $hash{...} is "if it looks like
          word, it doesn't have to be quoted". And - is not in the list of word
          characters as far as Perl is concerned.

          > My question: since Perl doesn't have constants, what exactly IS
          > foo-bar? Why is it 0?
          >
          > The behavior above seems inconsistent to me. Is it considered a bug?

          No. It's documented behaviour.

          For historical purposed, if you do not "use strict" then

          $var = foo;

          will be treated as

          $var = 'foo';

          if there is no subroutine named foo. It's called "bareword" and was a
          bad idea in my opinion. In your case you are subtracting two strings,
          'foo' and 'bar' which means both are evaluated to a number (zero) and
          then the zeroes are subtracted.

          print('foo' - 'bar');


          This can cause hard to find errors (if for example you mistype a
          subroutine name) so you should always start your scripts with

          use strict;

          which will prevent this.

          Jenda
          ===== Jenda@... === http://Jenda.Krynicky.cz =====
          When it comes to wine, women and song, wizards are allowed
          to get drunk and croon as much as they like.
          -- Terry Pratchett in Sourcery
        Your message has been successfully submitted and would be delivered to recipients shortly.