Forums

cue equals

General discussion about Cobra. Releases and general news will also be posted here.
Feel free to ask questions or just say "Hello".

cue equals

Postby nerdzero » Thu Jun 21, 2012 12:03 pm

If I write an equals cue, how am I supposed to use it?

Like this

a == b


or like this

a.equals(b)


The docs seem to imply the first way but only the second way passes my test.
nerdzero
 
Posts: 286
Location: Chicago, IL

Re: cue equals

Postby Charles » Thu Jun 21, 2012 4:21 pm

The bottom of the cue page says "Currently only "cue init" is fully supported". Sorry for any confusion. Nevertheless, Cobra's treatment of the == and <> operators does in fact look at the equals method. Here is a working example:
class Thing

cue init(i as int)
base.init
_i = i

pro i from var as int

# Cobra will invoke a strongly typed .equals method
# for == and <> between two statically typed things:
def equals(other as Thing) as bool
return other.i == .i

# Override Object.equals
# Cobra will use this in dynamic situations
# and the .NET libs may use this in others,
# such as using Thing as a key in a dictionary:
def equals(obj as Object?) as bool is override
if obj inherits Thing, return .equals(obj)
return false

# When you override Object.equals, you should override:
def getHashCode as int is override
return .i.getHashCode


class Program

def main
assert Thing(5) == Thing(5)
assert Thing(5) <> Thing(2)
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: cue equals

Postby nerdzero » Thu Jun 21, 2012 6:07 pm

Okay, thanks and yeah I saw the note at the bottom of the page but was maybe hoping it was out of date or I was just doing something wrong :)

However, based on what you've described, shouldn't the following code work since it would invoke the strongly typed equals?

# cobra --version
# Cobra svn:2683 (post 0.8) / 2012-06-01 on Mono 2.10.8.1 CLR v4.0.30319 on Ubuntu 12.04 LTS
# cobra eq_test.cobra

class Thing

cue init(i as int)
base.init
_i = i

pro i from var as int

def equals(other as Thing) as bool
return other.i == .i


class Program

def main
assert Thing(5) == (Thing(5))
assert Thing(5) <> (Thing(2))


Or is the strongly typed equals only called explicitly via an overridden dynamic equals?
nerdzero
 
Posts: 286
Location: Chicago, IL

Re: cue equals

Postby nerdzero » Thu Jun 21, 2012 6:12 pm

Whoops, those extra parenthesis in the asserts shouldn't be there. Regardless, it still fails.
nerdzero
 
Posts: 286
Location: Chicago, IL

Re: cue equals

Postby Charles » Thu Jun 21, 2012 7:07 pm

In response to this thread (but before I saw your post just above), I expanded on the example with changeset:2713 which includes a new "How To" which will eventually make it to the web site and help future newcomers. Here it is inline:
class Foo

cue init(i as int, s as String)
base.init
_i, _s = i, s

pro i from var as int

pro s from var as String

# Cobra will invoke a strongly type .equals method
# for == and <> between two statically typed objects:
def equals(other as Foo) as bool
return other.i == .i and other.s == .s

# Override Object.equals
# Cobra will use this in dynamic situations
# and the .NET libs may use this in others,
# such as using Foo as a key in a dictionary:
def equals(obj as Object?) as bool is override
if obj inherits Foo, return .equals(obj)
return false

# When you override Object.equals, you should override .getHashCode:
def getHashCode as int is override
return HashCodeUtils.combine(.i.getHashCode, .s.getHashCode)


class Program

def main
assert Foo(5, 'foo') == Foo(5, 'foo')
assert Foo(5, 'foo') <> Foo(2, 'foo')

The HashCodeUtils class is new so if you want to follow the above example, you will need to update to the latest.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: cue equals

Postby Charles » Thu Jun 21, 2012 7:09 pm

nerdzero wrote:...
However, based on what you've described, shouldn't the following code work since it would invoke the strongly typed equals?
...

You are correct that it should. And this is broken for me as well. Maybe this was not locked down by a test case and broke at some point. I will investigate.

In the meantime, your workaround is to also provide the Object.equals and .getHashCode overrides.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: cue equals

Postby Charles » Thu Jun 21, 2012 7:26 pm

Got it. I recalled incorrectly. It's not a statically typed .equals that the compiler looks for, it's a statically type .compareTo. This works:
class Thing

cue init(i as int)
base.init
_i = i

pro i from var as int

# def equals(other as Thing) as bool
# return other.i == .i

def compareTo(other as Thing) as int
return .i - other.i


class Program

def main
assert Thing(5) == Thing(5)
assert Thing(5) <> Thing(2)

I don't see any reason why it couldn't look for the statically defined .equals as well. I'll get this cleaned up and bust out a wiki page covering this topic.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: cue equals

Postby nerdzero » Thu Jun 21, 2012 7:39 pm

Cool, thanks for taking the time to look into this. If you do work on this later, don't forget to test if something is "in" a list :)
class Thing

cue init(i as int)
base.init
_i = i

pro i from var as int

def compareTo(other as Thing) as int
return .i - other.i


class Program

def main
things = List<of Thing>()
things.add(Thing(5))
assert Thing(5) in things #this will fail
nerdzero
 
Posts: 286
Location: Chicago, IL

Re: cue equals

Postby Charles » Fri Jun 22, 2012 12:08 am

Nice catch. :)
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: cue equals

Postby Charles » Sat Jul 07, 2012 9:14 pm

I have fixed the problem you found further above where the Cobra compiler was not making use of a strongly typed .equals method for == and <>. It still looks for .compareTo first, but when not found, it will look for .equals.

Regarding the "in" operator, that won't be fixed until we have a true "cue equals" which isn't planned for the 0.9 release. The How-To I created and referenced above though correctly shows overriding Object.equals and .getHashCode is part of the "recipe" for object equality. In other words, the workaround is easy.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Next

Return to Discussion

Who is online

Users browsing this forum: No registered users and 41 guests