473,758 Members | 2,401 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Providing backwards compatibility for serialized objects

Greetings!

Say that it's desirable to provide backwards compatibility for methods
of an object, consider the case where...

class Foo:
def bar (self, a, b):
pass

....is a defined class that can be serialized and later be deserialized.
This object is later changed so that it's defined as...

class Foo:
def bar (self, a, b, c): # note the different argument spec
pass

....old versions of Foo can still be deserialized but the new code relies
on the fact that new version has one more argument in the spec. In the
case were you wanted to provide backwards compatibility as general
solution you could do...

try:
fooObject.bar(a , b, c)

except TypeError:

import sys

if sys.exc_traceba ck.tb_next is not None:

# Don't capture the exception if the traceback object
# has more than one level, this *should* handle the case
# were there is a TypeError inside of the .bar method

raise

# else call it with the old signature
fooObject.bar(a , b)

....what are the draw backs of using this approach? Are there any cases
were this would break?

The better approach is just to break backwards compatibility or provide
a new method with a different name or another version of the class --
but consider the case were you don't have the luxury of proper design
decisions up front.

TIA,
Jason
Jul 18 '05 #1
1 1786

I've done something quite similar. I had two ways of doing it :

1- use default parameters

After deserializing, call a method on the object which will inspect it
and set all undefined fields to a default value. This method can have some
intelligence and use the right default value according to the state of the
object.

Good things :
- Simple
- Fast
Problems :
- Does not handle all problems correctly (a default is still a default)
- Not as evolved as the next solution
- Not very "clean"

2- serialize version information

When serializing, save a "format version" identifier, which says which
version of the object you have.
When loading the object, read this version spec and act accordingly,
setting default values, changing members, to bring the object to the
latest version. If you save it again, it'll be using the latest format
version.

Good things :
- Foolproof (encoded version number eliminates guessing)
Problem with your problem :
Serializing does not save the class methods and associated code, only the
object contents.
Thus if you update a method in class Foo, both the "old" and "new" object
will be deserialized into a new "Foo" instance with associated methods.
Thus if a method expects to find a member in new Foo which does not exist
in old Foo, it will fail. But if a method has different parameters like in
your example, you'll always get the new method, which is the one in your
class definition.

Thus, if you choose your default values well and code your methods
accordingly, everything should be okay when you change versions.

However, if you want the two versions of Foo to behave differently across
versions, you must make them two different classes. Say NewFoo and OldFoo
are subclasses of BaseFoo for instance. However, you'll have ot maintain
twice the code, which quickly becomes hell.
Greetings!

Say that it's desirable to provide backwards compatibility for methods
of an object, consider the case where...

class Foo:
def bar (self, a, b):
pass

...is a defined class that can be serialized and later be deserialized.
This object is later changed so that it's defined as...

class Foo:
def bar (self, a, b, c): # note the different argument spec
pass

...old versions of Foo can still be deserialized but the new code relies
on the fact that new version has one more argument in the spec. In the
case were you wanted to provide backwards compatibility as general
solution you could do...

try:
fooObject.bar(a , b, c)

except TypeError:

import sys

if sys.exc_traceba ck.tb_next is not None:

# Don't capture the exception if the traceback object
# has more than one level, this *should* handle the case
# were there is a TypeError inside of the .bar method

raise

# else call it with the old signature
fooObject.bar(a , b)

...what are the draw backs of using this approach? Are there any cases
were this would break?

The better approach is just to break backwards compatibility or provide
a new method with a different name or another version of the class --
but consider the case were you don't have the luxury of proper design
decisions up front.

TIA,
Jason


Jul 18 '05 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
2227
by: Nick Kerzman via MySQLMonster.com | last post by:
Any assistance would be greatly appreciated. I'm relatively new to working with MySQL. I exported my DB with phpMyAdmin 2.6.0-pl3 running MySQL 4.1.7 I'm trying to import it with phpMyAdmin 2.5.7-pl1 running MySQL 4.0.20 Is this possible? I seem to be getting this error: MySQL said:
0
1352
by: flat_ross | last post by:
If there was one thing nice about "Binary Compatibility" in VB6, it would tell you at compile time that you changed your public interface. I am looking for the same functionality in .NET. I know all the underlying stuff is different. But at the end of the day, I want to be told if the changes I made to my public interface are backwards compatible with an existing assembly. It is important to maintain backwards compatibility when...
7
2151
by: Sonny | last post by:
I need to port a library that is written entirely in C to C++. The library is supported on quite a few platforms (windows, Solaris, Linux, AIX, HP-UX, OSX, etc...) and there's quite an existing customer base that uses it. I need to maintain backwards compatibility such that existing users won't have to do anything to their existing applications other than a re-compile when they upgrade to this new version of the library. I figure that I...
0
1327
by: Ray Mitchell | last post by:
Hello, The result of auto-converting some Java code to C# yielded the following upgrade issue regarding the original Java call to "reset()": public virtual void writeObj(Object obj) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(thisStream, obj);
2
6208
by: Dominic | last post by:
Hi everybody, I'm planning to use serialization to persist an object (and possibly its child objects) in my application. However, I'm concerned about the backward compatibility issue. I'm evaluating if we can easily resolve this issue. For example, I have a class MyClass consisting of 100 fields.
7
3671
by: Neal Andrews | last post by:
Hi All, Does anyone know how to stop Events from being serialized in a class that uses the <Serializable()> attribute? I have tried using the <NonSerialized()> attribute but for some bizarre reason, it is not allowed on events. I am using VS 2003, if that makes any difference. The only thing I can think of is to wrap all the events in a separate class and then not to mark the class as Serializable.
70
4058
by: py | last post by:
I have function which takes an argument. My code needs that argument to be an iterable (something i can loop over)...so I dont care if its a list, tuple, etc. So I need a way to make sure that the argument is an iterable before using it. I know I could do... def foo(inputVal): if isinstance(inputVal, (list, tuple)): for val in inputVal: # do stuff
150
6571
by: tony | last post by:
If you have any PHP scripts which will not work in the current releases due to breaks in backwards compatibility then take a look at http://www.tonymarston.net/php-mysql/bc-is-everything.html and see if you agree with my opinion or not. Tony Marston http://www.tonymarston.net
0
1248
by: rlaemmler | last post by:
Hi, I just migrated my web app to .NET 2.0. Part of the app creates some business objects from a MySQL query which is returned by a web service. Some of those objects contain DateTime properties. Using .NET 1.1 soap serialized a DateTime always in the ISO8601 format. e.g. "2006-01-27T07:42:11.3014976-08:00". Now using .NET 2.0 suddenly the DateTime objects instanciated from a MySQL query get serialized as "2006-01-26T18:40:56". Only...
0
9299
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10076
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9885
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
7287
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6564
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5332
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3832
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3402
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2702
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.