in reply to Re: Can you spot the problem?
in thread Can you spot the problem?
Perl5's bitwise operators are not numeric operators; they also work on strings.
I know they also work on strings. I've been using and teaching Perl for nearly ten years now ;-)
All I mean by calling it a numerical operator is that if you give it a number you get a bitwise numerical operation. It performs a numerical operation (and a different string operation if you give it a string).
No, strings don't act like numbers, normally.
...
The only time strings ever get converted automagically into numbers is in numeric context.
Yes, this is the point I was trying to get across :-) Numerical context is exactly the thing that does make strings containing numbers act like numbers. This is the essence of what causes confusion with these operators for some Perl programmers.
Perl developers are used to the operator defining whether a scalar is treated as a string or a number. Want to add two numbers together use "+" and Perl will treat them as numbers. Want to combine two scalars use "." and Perl will treat them as strings.
Operators where numbers and strings would do different things (e.g. equality) are normally given different names (eq and ==).
This is an excellent piece of design by Larry because it makes the operation completely explicit. You don't have to force a particular context on your scalars. You don't have to know whether they contain a number or a string. Perl just DWIM.
The bitwise operators are the only place where this doesn't apply. You have two separate bits of functionality - numerical bitwise operations and string bitwise operations - with the same names. The numerical and string bitwise operations are even documented separately in perlop.
They do exactly the opposite of Perl's other operators. Rather than changing the type of the scalar depending on the function, they change the function depending on the type of the scalar.
In my opinion this was a mistake. Just like forcing people to disambiguate equality like this:
0+$foo == $bar # guarantee numerical equality "$foo" == $bar # guarantee string equality $foo == $bar # it depends...
would be a mistake.
Perl programmers are used to scalars and operators that DWIM. The bitwise operators often don't without extra work to coerce one of their arguments.
Then why did you think it would get changed into a number if you performed a bitwise operation on it?
I don't think that.
Would you expect "123" to change into 123 if you assigned it to a scalar, tested it with the defined operator, or passed it as an argument to an arbitrary user-defined function? No?
Of course not.
Then why did you think it would get changed into a number if you performed a bitwise operation on it?
I don't.
Were you under the impression that the bitwise operators supplied a numeric context to their arguments?
Nope.
We use them on strings at least as much as on numbers. It wouldn't make sense for them to supply numeric context. This is not "random breakage" to my way of thinking;
It's not "random breakage" in the sense that the current behaviour is the way the language is defined. However, unless your careful to make all bitwise operations explicitly on numbers or strings, it can lead to code that behaves in radically different ways depending on the scalars it is called with.
none of the bitwise operators ever impose a numeric context on their arguments, nor should they
Just to be clear I am not suggesting that the bitwise operations should force a numeric context :-)
What I am saying is that the decision to have one operator that does two completely different things depending on whether it is given a number or a string goes against the DWIM design of the rest of Perl.
0+$foo | $bar # guarantee numerical bitwise or "$foo" | $bar # guarantee string bitwise or $foo | $bar # ... it depends
This can cause confusion and the OP is an instance of this confusion.
. I was just trying to understand where you were coming from, why you thought the code should work, and what expectations Perl was breaking.
Ahhh. I think I see the source of confusion. I don't think that the code as written should have worked (it obviously doesn't). However I do think that the code "makes sense". By that I mean that the intent of the developer was clear (assuming you understand bitwise operations).
The mistake that was made was not realising that you needed to coerce one of the strings into a number to get a numerical bitwise-or rather than a string bitwise-or.
This may be, as you suggested, because they're used to a language where this would be the only possible interpretation.
However since I've seen experienced Perl developers make the same sort of mistake (myself included) this can't be the only reason confusion arises.
The design of Perl encourages you to forget about the difference between strings and numbers because the various operators will DWIM. Unfortunately the bitwise operators are one place where this doesn't happen - and that is another reason why people often make this sort of mistake.
Hopefully making some vague sort of sense :-)
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Can you spot the problem?
by Abigail-II (Bishop) on Mar 10, 2004 at 21:12 UTC | |
by adrianh (Chancellor) on Mar 10, 2004 at 21:39 UTC |