FAQ
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.

Search Discussions

  • Chas. Owens at Nov 15, 2008 at 7:55 pm

    On Sat, Nov 15, 2008 at 13:52, Kelly Jones wrote:
    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?
    snip

    First, Perl does have constants. See the constant* pragma and the
    Readonly** module for more information. But those are not constants;
    they are barewords. Barewords can be one of three things: an old
    style filehandle, a subroutine call, or a string. The use of the
    strict pragma turns off the last of these options (which is one of the
    many reasons it should nearly always be used). The reason the answer
    is zero is simple: a string minus a string is zero because a string in
    numeric context yields zero and a zero minus a zero is zero. Things
    would have become clearer if you had turned on either the warnings***
    or strict**** pargmas:

    perl -Mwarnings -le '$hash{"foo-bar"} = 1; print $hash{foo-bar}'
    Unquoted string "foo" may clash with future reserved word at -e line 1.
    Argument "bar" isn't numeric in subtraction (-) at -e line 1.
    Argument "foo" isn't numeric in subtraction (-) at -e line 1.
    Use of uninitialized value in print at -e line 1.

    perl -Mstrict -le 'my %hash; $hash{"foo-bar"} = 1; print $hash{foo-bar}'
    Bareword "foo" not allowed while "strict subs" in use at -e line 1.
    Bareword "bar" not allowed while "strict subs" in use at -e line 1.
    Execution of -e aborted due to compilation errors.

    * http://perldoc.perl.org/constant.html
    ** http://search.cpan.org/dist/Readonly/Readonly.pm
    *** http://perldoc.perl.org/warnings.html
    **** http://perldoc.perl.org/strict.html

    --
    Chas. Owens
    wonkden.net
    The most important skill a programmer can have is the ability to read.
  • John W. Krahn at Nov 15, 2008 at 8:10 pm

    Chas. Owens wrote:
    On Sat, Nov 15, 2008 at 13:52, Kelly Jones wrote:
    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?
    First, Perl does have constants. See the constant* pragma and the
    Readonly** module for more information. But those are not constants;
    they are barewords. Barewords can be one of three things: an old
    style filehandle, a subroutine call, or a string. The use of the
    strict pragma turns off the last of these options (which is one of the
    many reasons it should nearly always be used). The reason the answer
    is zero is simple: a string minus a string is zero because a string in
    numeric context yields zero and a zero minus a zero is zero. Things
    would have become clearer if you had turned on either the warnings***
    or strict**** pargmas:
    *******
    s/pargmas/pragmas/;


    :-)

    John
    --
    Perl isn't a toolbox, but a small machine shop where you
    can special-order certain sorts of tools at low cost and
    in short order. -- Larry Wall
  • Chas. Owens at Nov 15, 2008 at 8:47 pm
    On Sat, Nov 15, 2008 at 15:10, John W. Krahn wrote:
    snip
    s/pargmas/pragmas/;
    snip

    And I had paragams at one point. I need more (or better) sleep.

    --
    Chas. Owens
    wonkden.net
    The most important skill a programmer can have is the ability to read.
  • John W. Krahn at Nov 15, 2008 at 8:06 pm

    Kelly Jones wrote:
    Consider:

    perl -le '$hash{"foo-bar"} = 1; print $hash{foo-bar}'
    [no result]
    Using warnings and/or strict may have helped:

    $ perl -Mwarnings -le 'my %hash = ("foo-bar", 1); print $hash{foo-bar}'
    Unquoted string "foo" may clash with future reserved word at -e line 1.
    Argument "bar" isn't numeric in subtraction (-) at -e line 1.
    Argument "foo" isn't numeric in subtraction (-) at -e line 1.
    Use of uninitialized value in print at -e line 1.


    $ perl -Mstrict -le 'my %hash = ("foo-bar", 1); print $hash{foo-bar}'
    Bareword "foo" not allowed while "strict subs" in use at -e line 1.
    Bareword "bar" not allowed while "strict subs" in use at -e line 1.
    Execution of -e aborted due to compilation errors.

    perl -le '$hash{"foobar"} = 1; print $hash{foobar}'
    1
    $ perl -Mwarnings -le 'my %hash = ("foobar", 1); print $hash{foobar}'
    1

    $ perl -Mstrict -le 'my %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.
    Actually it sets $hash{"foo-bar"} to 1. There is a difference between
    the string "foo-bar" and the expression foo-bar.

    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?
    It is 'foo' - 'bar', unless either foo or bar can be resolved to a
    subroutine.

    Why is it 0?
    In numerical context strings are converted to numbers and if there are
    no leading numerical digits in the string they are converted to the
    number 0.

    $ perl -le'print "1234" - "123"'
    1111
    $ perl -le'print "1234junk" - "123garbage"'
    1111
    $ perl -le'print "junk1234" - "garbage123"'


    The behavior above seems inconsistent to me. Is it considered a bug?
    No, that is the defined behaviour.




    John
    --
    Perl isn't a toolbox, but a small machine shop where you
    can special-order certain sorts of tools at low cost and
    in short order. -- Larry Wall
  • Jenda Krynicky at Nov 15, 2008 at 10:42 pm
    From: "Kelly Jones" <kelly.terry.jones@gmail.com>
    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@Krynicky.cz === 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
  • Chas. Owens at Nov 16, 2008 at 1:42 am
    On Sat, Nov 15, 2008 at 17:42, Jenda Krynicky wrote:
    snip
    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.
    snip

    Not exactly. A hyphen is allowed at the start of a bareword as long
    as it doesn't look like it is part of an expression. So

    $foo = -foo;

    is the same as

    $foo = '-foo';

    Another oddity are ::

    $foo = Does::Not::Exist;

    is the same as

    $foo = 'Does::Not::Exist';

    And, of course, all of the characters in \w work

    $foo = foo_bar_123;

    is the same as

    $foo = 'foo_bar_123';

    There may be other characters that are allowed, but that is the extent
    of my knowledge.

    --
    Chas. Owens
    wonkden.net
    The most important skill a programmer can have is the ability to read.
  • Rob Dixon at Nov 16, 2008 at 1:41 am

    Kelly Jones wrote:
    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?
    I have said that I have no time for command-line perl. What you have published
    doesn't work on my platform, nor on many others.

    Of course I could rewrite the question in my head to a proper Perl program, but
    then I shall be looking for a bug either in my mental rewrite or in your
    original code.

    So since you can't be bothered to publish a proper Perl program, neither can I
    be bothered to interpret your question. What is more, nor will all the other
    people who could have answered your question wisely.

    Rob
  • Dr.Ruud at Nov 16, 2008 at 12:00 pm

    Rob Dixon schreef:
    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 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?
    I have said that I have no time for command-line perl. What you have
    published doesn't work on my platform, nor on many others.

    Of course I could rewrite the question in my head to a proper Perl
    program, but then I shall be looking for a bug either in my mental
    rewrite or in your original code.

    So since you can't be bothered to publish a proper Perl program,
    neither can I be bothered to interpret your question. What is more,
    nor will all the other people who could have answered your question
    wisely.
    Rob, start sparing us this. Perl isn't what you (and I) limit it to.

    --
    Affijn, Ruud

    "Gewoon is een tijger."
  • Rob Dixon at Nov 19, 2008 at 1:17 pm

    Dr.Ruud wrote:
    Rob Dixon schreef:
    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 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?
    I have said that I have no time for command-line perl. What you have
    published doesn't work on my platform, nor on many others.

    Of course I could rewrite the question in my head to a proper Perl
    program, but then I shall be looking for a bug either in my mental
    rewrite or in your original code.

    So since you can't be bothered to publish a proper Perl program,
    neither can I be bothered to interpret your question. What is more,
    nor will all the other people who could have answered your question
    wisely.
    Rob, start sparing us this. Perl isn't what you (and I) limit it to.
    I agree this did seem uncommonly grumpy of me. In particular I chose a bad
    example to criticize (although I still would have preferred to see just the Perl
    code rather than the entire command line).

    So I apologise, and will keep my comments better in context in the future.

    Rob
  • Brian McCauley at Nov 20, 2008 at 5:57 pm

    On Nov 15, 6:52 pm, kelly.terry.jo...@gmail.com (Kelly Jones) wrote:
    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 False.
    what exactly IS foo-bar? Why is it 0?
    'foo' - 'bar' or 0-0 which is zero.
    The behavior above seems inconsistent to me.
    The strict pragma disables 3 features of Perl that can be confusing if
    you don't realise that you are using them.
    The warnings pragma warns you of several more features of Perl that
    can be confusing if you don't realise that you are using them.

    In this case you are using the features bare-word strings (that would
    be disabled by strict) and implicit conversion of non-numeric strings
    to the number zero (that would be warned about by warnings).
    Is it considered a bug?
    The lack of "use strict" and "use warnings" at the top of your code
    should usually be considered a bug.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupbeginners @
categoriesperl
postedNov 15, '08 at 6:53p
activeNov 20, '08 at 5:57p
posts11
users7
websiteperl.org

People

Translate

site design / logo © 2022 Grokbase