Two points taken and 10x for the fix.
As for the user overload, I'm not sure I understood. Using overload from
main seems to have no effect. Running it from a package is what I already
have.
I'm still looking for the magic to make it a good module. The magic that
will allow this in main:
package main;
use no_coerced_strings;
ok("" ne undef);
and get away with it :)
On 17 May 2011 19:11, Gaal Yahas <[email protected]> wrote:
> To make it default (but not globally so), I think you should be able to
>
> use overload 'eq' => \&equals_no_coerce;
>
> Note that with your comparator, !(undef eq undef), which I'm not sure you
> want.
>
> Also, it's generally better to say "return" to return false, not "return
> 0".
>
> On Tue, May 17, 2011 at 12:43 PM, ynon perek <[email protected]> wrote:
>
>> Hi,
>> Regarding Javascript, I never forget the special === operator because I
>> have my vim configured to get mad when I use the other one. I also use some
>> automatic lint tools (jslint), which is like Perl::Critic only in JS that
>> checks using the non-coercing operator.
>>
>> I can see why undef eq "" is a feature, I just feel it's a wrong feature.
>> It should be the exception not the rule. Using fatal warnings helps in
>> finding and fixing, but not so much in preventing. (the hash was just an
>> example, coercion can be confusing in other places as well).
>> Just to be clear, I find it hard to think of a case where I actually had
>> encountered that warning, and left it in production code. The "use of
>> uninitialized value..." warning is almost always an indication for mistake.
>>
>> What I have in mind is something like this one (though I'm still not sure
>> how to make it the default):
>>
>> use strict;
>> use warnings;
>>
>> package NonCoercingString;
>> use subs qw/equals_no_coerce/;
>>
>> use Moose;
>> has 'data', is => 'ro', required => 1;
>>
>> use overload
>> 'eq' => \&equals_no_coerce,
>> 'ne' => sub { ! &equals_no_coerce };
>>
>> sub equals_no_coerce {
>> my ($self, $other, $swap) = @_;
>>
>> defined ($self->data) || return 0;
>> defined ($other) || return 0;
>>
>> return $self->data eq $other;
>> }
>>
>> package main;
>> use Test::More 'no_plan';
>> my $foo = NonCoercingString->new(data => '');
>>
>> # these both pass - good
>> ok($foo eq '');
>> ok($foo ne undef);
>>
>> # this one passes. Not so good
>> ok('' eq undef);
>>
>>
>>
>>
>> On 16 May 2011 13:16, Gaal Yahas <[email protected]> wrote:
>>
>>> Well, if you're worried you might forget checks, what would stop you from
>>> forgetting to use the special operator and using eq at some place?
>>>
>>> undef eq "" (with warning) is a feature of Perl. If you have a test
>>> suite, perhaps you can run it with Test::NoWarnings and look to maintain
>>> coverage. (In fact, maybe you want use warnings FATAL in your production
>>> code?)
>>>
>>> Another option is that when designing a data structure of particular
>>> importance, don't expose its native hash representation to users; force them
>>> to use some accessor interface over it instead and put assertions there.
>>>
>>> On Fri, May 13, 2011 at 1:02 AM, ynon perek <[email protected]> wrote:
>>>
>>>> Hi,
>>>> Obviously I do use the explicit notation, until that one time that I
>>>> forget ... For this program, the right solution includes yours *and*the
>>>> extra check on the dictionary.
>>>> Being more specific, these perl lines:
>>>>
>>>> die if ! exists $users{$username}; <---- I'd like to get rid of this
>>>> line
>>>>
>>>> if ( $users{$username} eq $password ) {
>>>> ...
>>>> }
>>>>
>>>> are pretty much this JS:
>>>>
>>>> if (users[username] === password) {
>>>> }
>>>>
>>>> The thing is, in JS I'm not afraid an underfined will turn out equal to
>>>> the empty string. (Well, I actually would fear it, if it wasn't for the
>>>> wonderful triple-equal operator).
>>>>
>>>>
>>>> On 13 May 2011 00:48, sawyer x <[email protected]> wrote:
>>>>
>>>>>
>>>>> On Thu, May 12, 2011 at 11:53 PM, ynon perek <[email protected]>wrote:
>>>>>
>>>>>> Hi,
>>>>>> Just found another one of them annoying bugs today - exemplified by
>>>>>> the code below. It's easy to see a non existent username will match an
>>>>>> empty
>>>>>> password (silent conversion between undef and empty string).
>>>>>> Javascript has an explicit equality operator that does not coerce
>>>>>> types (called the ===). In perl, I usually check for undefs (until I
>>>>>> forget). Is there such an operator for perl ?
>>>>>>
>>>>>
>>>>> You can (and should) use more explicit notation:
>>>>>
>>>>>
>>>>> chomp( my $username = <> );
>>>>> chomp( my $password = <> );
>>>>>
>>>>> defined $username && defined $password
>>>>> or die "Missing username and password";
>>>>>
>>>>> In a correct interface (if you're using web, this would be done in JS
>>>>> in the front, *and* in the back) you should be checking your input to make
>>>>> sure it was inserted correctly.
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Perl mailing list
>>>>> [email protected]
>>>>> http://mail.perl.org.il/mailman/listinfo/perl
>>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> Perl mailing list
>>>> [email protected]
>>>> http://mail.perl.org.il/mailman/listinfo/perl
>>>>
>>>
>>>
>>>
>>> --
>>> Gaal Yahas <[email protected]>
>>> http://gaal.livejournal.com/
>>>
>>> _______________________________________________
>>> Perl mailing list
>>> [email protected]
>>> http://mail.perl.org.il/mailman/listinfo/perl
>>>
>>
>>
>> _______________________________________________
>> Perl mailing list
>> [email protected]
>> http://mail.perl.org.il/mailman/listinfo/perl
>>
>
>
>
> --
> Gaal Yahas <[email protected]>
> http://gaal.livejournal.com/
>
> _______________________________________________
> Perl mailing list
> [email protected]
> http://mail.perl.org.il/mailman/listinfo/perl
>
_______________________________________________
Perl mailing list
[email protected]
http://mail.perl.org.il/mailman/listinfo/perl