|
|
Subscribe / Log in / New account

A little OO goes a long way

A little OO goes a long way

Posted May 3, 2013 15:53 UTC (Fri) by hummassa (subscriber, #307)
In reply to: A little OO goes a long way by jwakely
Parent article: Go and Rust — objects without class

Oh, the duplication is the least of the problems. A bigger one would be the combination of optimization by the programmer and external changes. So, the following code:

try {
  f = open(...)
  f.x()
  f.y()
  if( z ) f.writeCheckSumAndLastBuffer() else f.writeLastBuffer()
} finally {
  f.close()
}
generates a hidden bug when f.y(), that calls a w() function from an external library, starts seen some exception and the last buffer is not written. Bonus points if the "if(z)" thing was put by another programming, in the run of the normal maintenance of the program.


to post comments

A little OO goes a long way

Posted May 4, 2013 5:45 UTC (Sat) by danieldk (subscriber, #27876) [Link] (3 responses)

I don't see how that is a problem of try/finally. Consider this C++
{
   Resource someResource(...);
   resource.x();
   resource.y(); // throws
   resource.writeLastBuffer();
}

If y() throws here in C++, writeLastBuffer() is never called either. I if you always want to write something, add it to close() or ~Resource().

Also, Java 7 has a nicer try-with-resources statement, like Python's with, for classes that implement AutoClosable:

try (Resource r = new Resource(...)) {
  // Do something with r...
}

A little OO goes a long way

Posted May 4, 2013 10:21 UTC (Sat) by hummassa (subscriber, #307) [Link]

It still burdens the "client" programmer on remembering to use the new try thingy. Destructors have zero client programmer overhead.

A little OO goes a long way

Posted May 4, 2013 10:26 UTC (Sat) by hummassa (subscriber, #307) [Link]

> I don't see how that is a problem of try/finally.

You are right, of course. But using destructors you have a lot more chances that discovering that some code belong in an destructor and putting it there because in the client code the WriteLastBuffer thing sticks out like a sore thumb. :-D

Ah, and once you wrote it, all call sites are correct from now on.

A little OO goes a long way

Posted May 7, 2013 14:52 UTC (Tue) by IkeTo (subscriber, #2122) [Link]

Consider this C++
{
   Resource someResource(...);
   resource.x();
   resource.y(); // throws
   resource.writeLastBuffer();
}

C++ programmers are accustomed to a concept called RAII, Resource Acquisition is Initialization. So if they always want the last buffer written, they tend to write something like:

class LastBufferWriter {
public:
  LastBufferWriter(Resource resource): resource_(resource) {}
  ~LastBufferWriter() { resource_.writeLastBuffer(); }
private:
  Resource resource_;
};

... {
   Resource resource(...);
   LastBufferWriter writer(resource);
   // Anything below can throw or not throw, we don't care
   resource.x();
   resource.y();
}

Not to say that everybody like having to define a class for every cleanup, though. But with C++0x lambda expression, the above can easily be automated.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds