Jump to page: 1 2
Thread overview
InternetAddress comparison fail
Jan 03, 2015
Jonathan Marler
Jan 03, 2015
MattCoder
Jan 03, 2015
MattCoder
Jan 03, 2015
Jonathan Marler
Jan 03, 2015
MattCoder
Jan 03, 2015
Jonathan Marler
Jan 03, 2015
MattCoder
Jan 03, 2015
David Eagen
Jan 03, 2015
Jon
Jan 03, 2015
Jon
Jan 03, 2015
Jonathan Marler
Jan 03, 2015
Martin Nowak
Jan 04, 2015
Martin Nowak
Jan 04, 2015
Jonathan Marler
Jan 04, 2015
Jonathan Marler
Jan 03, 2015
Tobias Pankrath
Jan 04, 2015
Martin Nowak
January 03, 2015
Why doesn't the equals operator work on the InternetAddress class?

import std.stdio;
import std.socket;
void main()
{
  auto addr1 = new InternetAddress("192.168.0.1", 80);
  auto addr2 = new InternetAddress("192.168.0.1", 80);
  assert(addr1 == addr2); // FAILS
}

If I am not mistaken, the == operator is overriden by the opEquals method.  I don't see any opEquals method in std.socket so I'm wondering if this is by design or someone overlooked it?
January 03, 2015
On Saturday, 3 January 2015 at 01:16:39 UTC, Jonathan Marler wrote:
> Why doesn't the equals operator work on the InternetAddress class?

It fails as the example below:

import std.stdio;

class foo{}
void main(){
  auto a = new foo;
  auto b = new foo;
  assert(a == b);
}

I believe you need to compare the values inside those class right?

Anyway, the way I'd do this is changing the line:

assert(addr1 == addr2); // FAILS

to

assert(addr1.toAddrString() == addr2.toAddrString());

Matheus.
January 03, 2015
On Saturday, 3 January 2015 at 01:59:40 UTC, MattCoder wrote:
> I believe you need to compare the values inside those class right?

I forgot to paste an example:

import std.stdio;

class foo{
 int i = 0;
 bool opEquals(foo obj){ return this.i == obj.i;}	
}

void main(){
  auto a = new foo;
  auto b = new foo;
  assert(a.opEquals(b));
}

Matheus.
January 03, 2015
On Saturday, 3 January 2015 at 01:16:39 UTC, Jonathan Marler wrote:
> Why doesn't the equals operator work on the InternetAddress class?
>
> import std.stdio;
> import std.socket;
> void main()
> {
>   auto addr1 = new InternetAddress("192.168.0.1", 80);
>   auto addr2 = new InternetAddress("192.168.0.1", 80);
>   assert(addr1 == addr2); // FAILS
> }
>
> If I am not mistaken, the == operator is overriden by the opEquals method.  I don't see any opEquals method in std.socket so I'm wondering if this is by design or someone overlooked it?

I ran into this too and made a helper to do the comparison (using toAddrString) so I could move forward with my project.

Adding opEquals and opCmp is probably low-hanging fruit and a good place for someone to start working on Phobos.
January 03, 2015
On Saturday, 3 January 2015 at 03:11:05 UTC, David Eagen wrote:
> On Saturday, 3 January 2015 at 01:16:39 UTC, Jonathan Marler wrote:
>> Why doesn't the equals operator work on the InternetAddress class?
>>
>> import std.stdio;
>> import std.socket;
>> void main()
>> {
>>  auto addr1 = new InternetAddress("192.168.0.1", 80);
>>  auto addr2 = new InternetAddress("192.168.0.1", 80);
>>  assert(addr1 == addr2); // FAILS
>> }
>>
>> If I am not mistaken, the == operator is overriden by the opEquals method.  I don't see any opEquals method in std.socket so I'm wondering if this is by design or someone overlooked it?
>
> I ran into this too and made a helper to do the comparison (using toAddrString) so I could move forward with my project.
>
> Adding opEquals and opCmp is probably low-hanging fruit and a good place for someone to start working on Phobos.

Still, shouldn't the == operator do a deep compare of the two InternetAddress objects in the absence of a defined opEquals method? I don't see why it should fail in the above example.

-Jon
January 03, 2015
On 1/3/15 12:32 AM, Jon wrote:

> Still, shouldn't the == operator do a deep compare of the two
> InternetAddress objects in the absence of a defined opEquals method? I
> don't see why it should fail in the above example.

InternetAddress is a class. Default comparison for class is identity (refer to the same object).

-Steve

January 03, 2015
On Saturday, 3 January 2015 at 05:40:33 UTC, Steven Schveighoffer wrote:
> On 1/3/15 12:32 AM, Jon wrote:
>
>> Still, shouldn't the == operator do a deep compare of the two
>> InternetAddress objects in the absence of a defined opEquals method? I
>> don't see why it should fail in the above example.
>
> InternetAddress is a class. Default comparison for class is identity (refer to the same object).
>
> -Steve

Thanks for clearing that up - it's been a while since I've played with D. Maybe back in D1 it did a deep compare?

The docs still refer to == as doing a comparison of the object's contents though, unless I'm misreading it.

Under http://dlang.org/expression: "For class objects, the == and != operators compare the contents of the objects." Maybe this needs to be updated.

Thanks,
 -Jon
January 03, 2015
On 1/3/15 12:51 AM, Jon wrote:
> On Saturday, 3 January 2015 at 05:40:33 UTC, Steven Schveighoffer wrote:
>> On 1/3/15 12:32 AM, Jon wrote:
>>
>>> Still, shouldn't the == operator do a deep compare of the two
>>> InternetAddress objects in the absence of a defined opEquals method? I
>>> don't see why it should fail in the above example.
>>
>> InternetAddress is a class. Default comparison for class is identity
>> (refer to the same object).
>>
>> -Steve
>
> Thanks for clearing that up - it's been a while since I've played with
> D. Maybe back in D1 it did a deep compare?
>
> The docs still refer to == as doing a comparison of the object's
> contents though, unless I'm misreading it.
>
> Under http://dlang.org/expression: "For class objects, the == and !=
> operators compare the contents of the objects." Maybe this needs to be
> updated.

I can see how the wording is confusing, but that statement is somewhat out of context. What it really means is that == and != *should* be comparing the contents.

It is an explanatory statement as to why you cannot call

obj == null;

Because this translates to obj.opEquals(null), if obj is null, then it crashes (well, at least it used to).

The true definition of the default is here:

https://github.com/schveiguy/druntime/blob/master/src/object_.d#L107

-Steve
January 03, 2015
On Saturday, 3 January 2015 at 06:01:24 UTC, Steven Schveighoffer wrote:
> On 1/3/15 12:51 AM, Jon wrote:
>> On Saturday, 3 January 2015 at 05:40:33 UTC, Steven Schveighoffer wrote:
>>> On 1/3/15 12:32 AM, Jon wrote:
>>>
>>>> Still, shouldn't the == operator do a deep compare of the two
>>>> InternetAddress objects in the absence of a defined opEquals method? I
>>>> don't see why it should fail in the above example.
>>>
>>> InternetAddress is a class. Default comparison for class is identity
>>> (refer to the same object).
>>>
>>> -Steve
>>
>> Thanks for clearing that up - it's been a while since I've played with
>> D. Maybe back in D1 it did a deep compare?
>>
>> The docs still refer to == as doing a comparison of the object's
>> contents though, unless I'm misreading it.
>>
>> Under http://dlang.org/expression: "For class objects, the == and !=
>> operators compare the contents of the objects." Maybe this needs to be
>> updated.
>
> I can see how the wording is confusing, but that statement is somewhat out of context. What it really means is that == and != *should* be comparing the contents.
>
> It is an explanatory statement as to why you cannot call
>
> obj == null;
>
> Because this translates to obj.opEquals(null), if obj is null, then it crashes (well, at least it used to).
>
> The true definition of the default is here:
>
> https://github.com/schveiguy/druntime/blob/master/src/object_.d#L107
>
> -Steve

So what is the right way to compare the contents of 2 classes?  I thought it was to implement an opEquals method.  It pains me to see people using the toAddrString function to compare Address classes:(  This is so inefficient and unnecessary.
January 03, 2015
On Saturday, 3 January 2015 at 01:59:40 UTC, MattCoder wrote:
> On Saturday, 3 January 2015 at 01:16:39 UTC, Jonathan Marler wrote:
>> Why doesn't the equals operator work on the InternetAddress class?
>
> It fails as the example below:
>
> import std.stdio;
>
> class foo{}
> void main(){
>   auto a = new foo;
>   auto b = new foo;
>   assert(a == b);
> }
>
> I believe you need to compare the values inside those class right?
>
> Anyway, the way I'd do this is changing the line:
>
> assert(addr1 == addr2); // FAILS
>
> to
>
> assert(addr1.toAddrString() == addr2.toAddrString());
>
> Matheus.

Thanks for the suggestion.  However, it brings me a little pain to see people use the toAddrString for comparison.  An InternetAddress consists of a uint address and a ushort port.  The comparison should be 2 integer comparisons.  Using toAddrString results in the following steps:

1. Allocate memory for the InternetAddress (GC memory by the way)
2. Convert the uint address to an IP Address string
3. Convert the ushort port to a string.
4. Do steps 1-3 to the second InternetAddress
5. Do a string comparision with the two InternetAddresses.

This is so inefficient it hurts me.  The steps should be:

1. Compare the uint and ushort members of InternetAddress.

done.  Anyway, your suggestion works...but I hope you can understand why it hurts me to see it...lol
« First   ‹ Prev
1 2