Comparison operator overloading for class in D? - oop

I am currently learning D and struggling to understand how operator overloading could work for a class? Overriding opCmp makes sense and works correctly for a struct, but for a class it requires taking the right hand side as a Object instead of as my type.
This means I can't access any members to do a comparison. What's the point in the overload then? Am I missing something?

Sure you can access your members:
class MyClass {
int member;
override int opCmp(Object other) {
if (auto mcOther = cast(MyClass)other) {
// other, and thus mcOther, is an instance of MyClass.
// So we can access its members normally:
return member < mcOther.member ? -1
: member > mcOther.member ? 1
: 0;
} else {
// other is not a MyClass, so we give up:
assert(0, "Can't compare MyClass with just anything!");
}
}
}
The reason opCmp for classes takes Object as a parameter is it's being introduced in the Object class, from which every D class derives. Introducing opCmp there was a sensible choice back in the day, but less so now. However, since we don't want to break every piece of D code out there that uses opCmp (and opEquals, toHash and toString) with classes, we're kinda stuck with that choice.

Related

Creating the analogue of BigInteger.ZERO for own data type in Kotlin

So, as is well-known, Kotlin is able to access Java libraries, and among them is the BigInteger class. And this class has a very handy feature: There is a keyword, called "BigInteger.ZERO", which returns a BigInteger object whose value equals zero.
Now I am writing a fraction data type, and I'd very much like to do the same thing for it. But the problem with just putting a val inside the class is that this first needs an object to begin with; it's not a "static" constant, so to say.
I'd be very grateful indeed for any forthcoming replies.
You can put the constant as a val inside the companion object of your class:
class Fraction {
...
companion object {
val ZERO = Fraction()
}
}
Then you can call your constant by Fraction.ZERO.
Note that this only makes sense if your fraction class is immutable.

Refer to nested objects without full qualification

I have code (all of which I control) that looks like the following:
class FirstVeryLongName {
object ObjectA
object ObjectB
object ObjectC
}
class SecondVeryLongName {
object ObjectB
object ObjectD
}
The code I need to write is equivalent to
operation1(FirstVeryLongName.ObjectA, FirstVeryLongName.ObjectB)
operation2(SecondVeryLongName.ObjectB, SecondVeryLongName.ObjectD)
...except that the repeated uses of the very long names add a lot of clutter.
Here is something I hoped would work, but doesn't seem to:
FirstVeryLongName.run {
operation1(ObjectA, ObjectB)
}
...which I wasn't able to make work, even if I tried moving ObjectA and ObjectB into the companion of FirstVeryLongName and writing
FirstVeryLongName.Companion.run { ... }
...which I had hoped would give unqualified access to the objects, as it would have for a val in the companion object.
One thing I specifically want to avoid is typealiases or importing them as aliased names. I want it to be obvious without cross-references or manually looking at the imports where these are all coming from.
Is there some trick that would let me write this code and write FirstVeryLongName, ObjectA, and ObjectB each exactly once?
It makes sense to me that it isn't working the way you tried it.
The class name itself is no instance and run or with therefore doesn't apply. It's the same as just writing the package name and nothing else. This doesn't work either.
Regarding the Companion-approach, I assume you implemented the following:
class FirstVeryLongName {
companion object {
object ObjectA
object ObjectB
object ObjectC
}
}
and a usage such as:
with(FirstVeryLongName.Companion) {
operation1(ObjectA, ObjectB)
}
Actually this could work as long as you have such properties defined for the companion (this applies to functions as well). Actually that is also something you mentioned yourself. You may want to look at the generated byte code to see what an object actually corresponds to, if you didn't do it already. If you did, you can skip the rest of this paragraph ;-) Think of it as if it were just nested classes. In the example above we therefore have 3 nested classes inside the Companion-class, which is inside the FirstVeryLongName-class.
From Kotlin the access to the singleton INSTANCE-field is hidden from you. In the Kotlin code FirstVeryLongName.Companion.ObjectA can represent both, the type and the singleton instance reference. The context is relevant.
As you can't use class-names-only or part of an import-statement in run/with, you can't also simplify the access to the singleton instance in this way.
You can however do something as follows. Note: I clearly do not recommend this approach as is (I do not believe that you really need both: the object and the val). Maybe you can also use an object expression there? There is most probably an easier way to structure your code, but without appropriate context I can only guess... I may be wrong):
class FirstVeryLongName {
companion object {
val ObjectA = FirstVeryLongName.ObjectA // can you use an object expression here?
val ObjectB = FirstVeryLongName.ObjectA
val ObjectC = FirstVeryLongName.ObjectA
}
object ObjectA
object ObjectB
object ObjectC
}
Now the run/with works as you desire, but now it actually accesses the val-reference which points to the object:
with(FirstVeryLongName.Companion) {
operation1(ObjectA, ObjectB)
}
Just showing a simple example using an object expression. You may either want to have a common superclass, interface or, if you do not mind, you can even use object : Any() here:
class FirstVeryLongName {
companion object {
val ObjectA = object : interfaces.ObjectA { /* ... */ }
// ...
}
}
Usage still looks the same. Now only the signature of operation1 may differ.

Method returns an object of a different class

I have noticed a situation where there is a class (say: ClassA) with variable declarations and various methods. And in another class (say: Class B), there is a method(MethodofClassB()) with the return type of the method as ClassA.
so it is like:
Class A
{
variable i,j;
public int MethodA()
{
//some operation
}
}
Class B
{
variable x,y;
public static A MethodB()
{
//some operation
return obj;
}
}
1) I understand that MethodB() return an object of ClassA. Waty would be the use(the intention) of returning the object of ClassA
2) What is the reason for defining MethodB() as Public static. what would happen if static was not used for MethodB()
3)What would the returned objct look like. I mean if my method returned an integer, it would return some numerical value say '123' . If a method returns an object of a class, what would be in the returrned value.
please help me understand this with a small example
1) I understand that MethodB() return an object of ClassA. Waty would be the use(the intention) of returning the object of ClassA
Depends on what the method does, which isn't illustrated in this example. If the result of the operation is an instance of A then it stands to reason that it would return an instance of A, whatever A is.
For example, if A is a Car and B is a CarFactory then the method is likely producing a new Car. So it would return a Car that's been produced.
2) What is the reason for defining MethodB() as Public static. what would happen if static was not used for MethodB()
public allows it to be accessed by other objects. static means it's not associated with a particular instance of B. Both are subjective based, again, on the purpose of the method (which isn't defined in the example). Being static, it can be called as such:
var newInstance = B.MethodB();
If it wasn't static then an instance of B would be required:
var objectB = new B();
var newInstance = objectB.MethodB();
There are more and more implications here, including things like memory/resource usage and thread safety. All stemming from the purpose and business logic meaning of what B is and what MethodB does.
3)What would the returned objct look like. I mean if my method returned an integer, it would return some numerical value say '123' . If a method returns an object of a class, what would be in the returrned value.
It would be an instance of A. Similar to creating an instance here:
var objectA = new A();
This method also creates (or in some way gets) an instance:
var objectA = B.MethodB();
Without knowing more about what A is, what its constructor does, and what MethodB does, these two operations are otherwise the same.
First, your code is incorrect. There is no "ClassA" class. The class name is A, so the return type should be A not ClassA.
Second, the standard Java coding standards say to start methods and variables with lower case letters. So, your example should have been:
Class A
{
A anA;
B aB;
public int methodA()
{
//some operation
}
}
Class B
{
SomeType x, y;
public static A methodB()
{
//some operation
return obj;
}
}
David's answer shortly before mine is technically correct on points 1 and 2, although he also uses your mistake of calling the A type ClassA. His code for his answer to point 3, though, is incorrect and misleading. I would change his wording to this:
`3)What would the returned objct look like. I mean if my method returned an
integer, it would return some numerical value say '123' . If a method returns
an object of a class, what would be in the returrned value`.
It would be an instance of class A. Similar to creating an instance here:
A objectA = new A();
This method also creates (or in some way gets) an instance:
A objectA = B.methodB();
Without knowing more about what class A is, what its constructor does, and what methodB does, these two operations are otherwise the same.

code in the middle is different, everything else the same

I often have a situation where I need to do:
function a1() {
a = getA;
b = getB;
b.doStuff();
.... // do some things
b.send()
return a - b;
}
function a2() {
a = getA;
b = getB;
b.doStuff();
.... // do some things, but different to above
b.send()
return a - b;
}
I feel like I am repeating myself, yet where I have ...., the methods are different, have different signatures, etc..
What do people normally do? Add an if (this type) do this stuff, else do the other stuff that is different? It doesn't seem like a very good solution either.
Polymorphism and possibly abstraction and encapsulation are your friends here.
You should specify better what kind of instructions you have on the .... // do some things part. If you're always using the same information, but doing different things with it, the solution is fairly easy using simple polymorphism. See my first revision of this answer. I'll assume you need different information to do the specific tasks in each case.
You also didn't specify if those functions are in the same class/module or not. If they are not, you can use inheritance to share the common parts and polymorphism to introduce different behavior in the specific part. If they are in the same class you don't need inheritance nor polymorphism.
In different classes
Taking into account you're stating in the question that you might need to make calls to functions with different signature depending on the implementation subclass (for instance, passing a or b as parameter depending on the case), and assuming you need to do something with the intermediate local variables (i.e. a and b) in the specific implementations:
Short version: Polymorphism+Encapsulation: Pass all the possible in & out parameters that every subclass might need to the abstract function. Might be less painful if you encapsulate them in an object.
Long Version
I'd store intermediate state in generic class' member, and pass it to the implementation methods. Alternatively you could grab the State from the implementation methods instead of passing it as an argument. Then, you can make two subclasses of it implementing the doSpecificStuff(State) method, and grabbing the needed parameters from the intermediate state in the superclass. If needed by the superclass, subclasses might also modify state.
(Java specifics next, sorry)
public abstract class Generic {
private State state = new State();
public void a() {
preProcess();
prepareState();
doSpecificStuf(state);
clearState();
return postProcess();
}
protected void preProcess(){
a = getA;
b = getB;
b.doStuff();
}
protected Object postProcess(){
b.send()
return a - b;
}
protected void prepareState(){
state.prepareState(a,b);
}
private void clearState() {
state.clear();
}
protected abstract doSpecificStuf(State state);
}
public class Specific extends Generic {
protected doSpecificStuf(State state) {
state.getA().doThings();
state.setB(someCalculation);
}
}
public class Specific2 extends Generic {
protected doSpecificStuf(State state) {
state.getB().doThings();
}
}
In the same class
Another possibility would be making the preProcess() method return a State variable, and use it inthe implementations of a1() and a2().
public class MyClass {
protected State preProcess(){
a = getA;
b = getB;
b.doStuff();
return new State(a,b);
}
protected Object postProcess(){
b.send()
return a - b;
}
public void a1(){
State st = preProcess();
st.getA().doThings();
State.clear(st);
return postProcess();
}
public void a2(){
State st = preProcess();
st.getB().doThings();
State.clear(st);
return postProcess();
}
}
Well, don't repeat yourself. My golden rule (which admittedly I break from time on time) is based on the ZOI rule: all code must live exactly zero, one or infinite times. If you see code repeated, you should refactor that into a common ancestor.
That said, it is not possible to give you a definite answer how to refactor your code; there are infinite ways to do this. For example, if a1() and a2() reside in different classes then you can use polymorphism. If they live in the same class, you can create a function that receives an anonymous function as parameter and then a1() and a2() are just wrappers to that function. Using a (shudder) parameter to change the function behavior can be used, too.
You can solve this in one of 2 ways. Both a1 and a2 will call a3. a3 will do the shared code, and:
1. call a function that it receives as a parameter, which does either the middle part of a1 or the middle part of a2 (and they will pass the correct parameter),
- or -
2. receive a flag (e.g. boolean), which will tell it which part it needs to do, and using an if statement will execute the correct code.
This screams out loud for the design pattern "Template Method"
The general part is in the super class:
package patterns.templatemethod;
public abstract class AbstractSuper {
public Integer doTheStuff(Integer a, Integer b) {
Integer x = b.intValue() + a.intValue();
Integer y = doSpecificStuff(x);
return b.intValue() * y;
}
protected abstract Integer doSpecificStuff(Integer x);
}
The spezific part is in the subclass:
package patterns.templatemethod;
public class ConcreteA extends AbstractSuper {
#Override
protected Integer doSpecificStuff(Integer x) {
return x.intValue() * x.intValue();
}
}
For every spezific solution you implement a subclass, with the specific behavior.
If you put them all in an Collection, you can iterate over them and call always the common method and evry class does it's magic. ;)
hope this helps

Best design for lookup-and-possibly-change method

I am designing a class that stores (caches) a set of data. I want to lookup a value, if the class contains the value then use it and modify a property of the class. I am concerned about the design of the public interface.
Here is how the class is going to be used:
ClassItem *pClassItem = myClass.Lookup(value);
if (pClassItem)
{ // item is found in class so modify and use it
pClassItem->SetAttribute(something);
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
However I don't want to have to expose ClassItem to this client (ClassItem is an implementation detail of MyClass).
To get round that the following could be considered:
bool found = myClass.Lookup(value);
if (found)
{ // item is found in class so modify and use it
myClass.ModifyAttribute(value, something);
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
However this is inefficient as Modify will have to do the lookup again. This would suggest a lookupAndModify type of method:
bool found = myClass.LookupAndModify(value, something);
if (found)
{ // item is found in class
... // use myClass
}
else
{ // value doesn't exist in the class so add it
myClass.Add(value, something);
}
But rolling LookupAndModify into one method seems like very poor design. It also only modifies if value is found and so the name is not only cumbersome but misleading as well.
Is there another better design that gets round this issue? Any design patterns for this (I couldn't find anything through google)?
Actually std::set<>::insert() does precisely this. If the value exists, it returns the iterator pointing to the existing item. Otherwise, the iterator where the insertion was made is returned.
It is likely that you are using a similar data structure for fast lookups anyway, so a clean public interface (calling site) will be:
myClass.SetAttribute(value, something)
which always does the right thing. MyClass handles the internal plumbing and clients don't worry about whether the value exists.
Two things.
The first solution is close.
Don't however, return ClassItem *. Return an "opaque object". An integer index or other hash code that's opaque (meaningless) to the client, but usable by the myClass instance.
Then lookup returns an index, which modify can subsequently use.
void *index = myClass.lookup( value );
if( index ) {
myClass.modify( index, value );
}
else {
myClass.add( value );
}
After writing the "primitive" Lookup, Modify and Add, then write your own composite operations built around these primitives.
Write a LookupAndModify, TryModify, AddIfNotExists and other methods built from your lower-level pieces.
This assumes that you're setting value to the same "something" in both the Modify and Add cases:
if (!myClass.AddIfNotExists(value, something)) {
// use myClass
}
Otherwise:
if (myClass.TryModify(value, something)) {
// use myClass
} else {
myClass.Add(value, otherSomething);
}