Re: my least favorite perl feature
by Zaxo (Archbishop) on Feb 05, 2003 at 20:55 UTC
|
Time to breathe in the Zen.
Perl stringifies and numifies things at need. Scalars silently become strings for printing, numbers for arithmetic.
When you choose between == and eq don't think of it as forced by the nature of the scalar. Think of it as choosing for yourself how the comparison will be done.
After Compline, Zaxo
| [reply] [Watch: Dir/Any] |
|
After breathing some Zen, I still wish there was some sort of 'object equivalence testing operator' in Perl. I could use it to compare two hashes, or two arrays, or objects, or whatever, and it would give me a same/not-same response.
| [reply] [Watch: Dir/Any] |
|
if (@array1 == @array2)
very useful. I wouldn't want to miss it.
Furthermore, you'd have a hard time convincing me that you
need to do less work for redefining an operator than for
defining a function. Why not create a function that compares
two arrays?
Lastly, perl6 will have a supermatching operator. It will do
all kinds of different things, depending on the types of its
operands. Perhaps your idea of comparing arrays is one of
the possible options.
Abigail | [reply] [Watch: Dir/Any] [d/l] |
Re: my least favorite perl feature
by tall_man (Parson) on Feb 05, 2003 at 21:07 UTC
|
What is "overloaded" by design in perl is two possible values for every scalar: a string or a number. The comparison operators let you choose which. Do you want to give up either lexical or numeric sorting by overloading "<=>"?
By the way, if you "use warnings" perl will help you out, like so:
Argument "bbb" isn't numeric in numeric eq (==) at ddd.pl line 4.
| [reply] [Watch: Dir/Any] [d/l] |
|
I would "use warnings", but in mason, it just isn't useful. For example, here's the message I get back when I "use warnings":
Mason error
error in file: /usr/local/lib/perl5/5.6.0/Carp/Heavy.pm
line 79: Bizarre copy of HASH in aassign
context: ...
75: # them according to the format variables defined earlier in
76:
# this file and join them onto the $sub sub-routine str
+ing
77:
if ($hargs) {
78:
# we may trash some of the args so we take a copy
79:
@a = @DB::args; # must get local copy of args
80:
# don't print any more than $MaxArgNums
81:
if ($MaxArgNums and @a > $MaxArgNums) {
82:
# cap the length of $#a and set the last element to '..
+.'
83:
$#a = $MaxArgNums;
...
component stack:
/orders_survey/search.html
code stack:
/usr/local/lib/perl5/5.6.0/Carp/Heavy.pm:79
See what I mean? | [reply] [Watch: Dir/Any] [d/l] |
|
| [reply] [Watch: Dir/Any] |
Re: my least favorite perl feature
by Elian (Parson) on Feb 05, 2003 at 21:40 UTC
|
Perl 6 will keep == as numeric comparison and eq as string comparison, though you'll be able to overload them if you want, though you can now.
There'll also be more effective "are these two objects the same object" and "are these two objects functionally equivalent" comparisons, though I don't know that they'll get punctuation. | [reply] [Watch: Dir/Any] |
Re: my least favorite perl feature
by hding (Chaplain) on Feb 05, 2003 at 22:15 UTC
|
Though
this article deals with Lisp rather than Perl,
the point is the same: equality (and its cousin copying) are rather difficult concepts, and it's rather impossible to get an operation involving them to automatically do the "right thing" all of the time, because there are many conflicting and incompatible yet individually perfectly valid notions of what the right thing is.
| [reply] [Watch: Dir/Any] |
Re: my least favorite perl feature
by BrowserUk (Patriarch) on Feb 05, 2003 at 21:49 UTC
|
print '100 is numerically ', 100 == $_ ? ' the same ' :' different, ',
+
'and lexically ', 100 eq $_ ? ' the same ' : ' different', ' to ',
+ "$_", $/
for qw[100 100.0 1e2 .1e3 1000e-1]
100 is numerically the same and lexically the same to 100
100 is numerically the same and lexically different to 100.0
100 is numerically the same and lexically different to 1e2
100 is numerically the same and lexically different to .1e3
100 is numerically the same and lexically different to 1000e-1
Examine what is said, not who speaks.
The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead. | [reply] [Watch: Dir/Any] [d/l] |
|
I don't have a python interpreter to double check - but I'm pretty sure that python == would be true for all the pairs of numbers you give (since numbers are automatically converted to a common type in python comparisons.)
<update>If they are numbers I mean. For strings only "100" == "100" returns true, all others false. If one a string and the other a number, always false.</update>
For objects == is true in python if they are the same object (in perl refaddr($o1) == refaddr($o2).
For full details see this bit of the python docs.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
is that python's == operator can be used to test different objects, like tuples, class objects, whatever.
| [reply] [Watch: Dir/Any] |
|
a) I'd still like to see the answer to the preceeding question as I have no knowledge of how Python would differeciate the examples I gave.
b) Could you give a couple of examples of where you use == in Python where you cannot in Perl? Again partly for my interest, partly because it ia easier understand you meaning from concrete examples than nebulous statements.
Examine what is said, not who speaks.
The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.
| [reply] [Watch: Dir/Any] |
Same number, different string [Re: my least favorite perl feature]
by bronto (Priest) on Feb 06, 2003 at 15:47 UTC
|
Actually, your problem doesn't have a simple solution. Two equal strings surely have the same numerical values, but what about two different strings? According to perlnumber these different strings all have the same numerical value: 1, 0x1, 01, 0b00000001
So, when $a eq $b says they are different, what would you do? I'll compare with == then! It's a simple or!. Gotcha! I am sorry, it's wrong: try to see what happens with ($a,$b) = qw(x y)...
What then? Well, when they are stringwise different, you have to choose again if you want to make a numerical comparison or not. You could check (by means of a regexp, for example) if $a and $b look like a number. If they don't, they are different and that's the end of the game; if they both are numbers you can (finally) proceed with ==
I had liked to find a better solution, but I think there isn't any.
Ciao! --bronto
The very nature of Perl to be like natural language--inconsistant and full of dwim and special cases--makes it impossible to know it all without simply memorizing the documentation (which is not complete or totally correct anyway).
--John M. Dlugosz
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
I don't think a simple solution was being asked for - just a solution ;-)
Equality is a bit of a bugger since it can mean so many different things. Perl gives us string and number equality - but their are others. For example Common Lisp provides eq, eql, equal, =, string-equal and char-equal - which all do slightly different things.
I miss "the same object" equals quite a bit in my coding (eq in Common Lisp). waxmop wants something like Common Lisp's equal.
| [reply] [Watch: Dir/Any] |
Re: my least favorite perl feature
by Aristotle (Chancellor) on Feb 06, 2003 at 12:27 UTC
|
| [reply] [Watch: Dir/Any] |
|
Not hard obviously ;-) However, I do miss the ability to say succinctly whether two things are the same "object" or not - something like Common Lisp's eq, Pop-11's == or python's is.
I admit Perl's eq works for this case 99% of the time, I don't like using it for identity checks because:
- It's not explicit enough. I want to say "these two things are the same" not "these two things expressed as strings are the same"
- Stringification has got to be more expensive than a direct comparison internally.
- It can fail when you have overloading of eq or "". I don't like writing code that can fail, even if it is only a few edge cases :-)
It's easy to write your own obviously - this does the job:
#! /usr/bin/perl
use strict;
use warnings;
use Scalar::Util qw(refaddr);
sub same {
ref($_[0]) && ref($_[1]) && refaddr($_[0]) == refaddr($_[1])
|| refaddr(\$_[0]) == refaddr(\$_[1]);
};
use Test::More 'no_plan';
our ($x, $y, $z) = (1,1);
*z = *x;
ok same($x, $x), 'x is x';
ok same(\$x, \$x), 'ref x is ref x';
ok !same($x, $y), 'x not y';
ok same($x, $z), 'x is z';
But, in my opinion, something this basic should be in the base language... but I guess that's what perl6 is for :-)
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] [d/l] |
|
|
|