| Thread overview | |||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 03, 2015 InternetAddress comparison fail | ||||
|---|---|---|---|---|
| ||||
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 Re: InternetAddress comparison fail | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan Marler | 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 Re: InternetAddress comparison fail | ||||
|---|---|---|---|---|
| ||||
Posted in reply to MattCoder | 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 Re: InternetAddress comparison fail | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan Marler | 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 Re: InternetAddress comparison fail | ||||
|---|---|---|---|---|
| ||||
Posted in reply to David Eagen | 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 Re: InternetAddress comparison fail | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jon | 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 Re: InternetAddress comparison fail | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: InternetAddress comparison fail | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jon | 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 Re: InternetAddress comparison fail | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: InternetAddress comparison fail | ||||
|---|---|---|---|---|
| ||||
Posted in reply to MattCoder | 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
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply