Henrik Sperre Johansen wrote:
On 28.12.2011 05:46, Ben Coman wrote:
<snip>
adoptInstance: only works when the object shapes are the same. (It only switches the class pointer in the object's header, and does not touch any contents) This is no longer true when the class you switch to have additional variables.
I was hoping that adding an instance variable to a subclass did not change the shape from the perspective of the superclass methods accessing superclass instance variables.
<snip>
You could act preemtively, and create an extension in your package:
ODBCRow >> #basicNew
    ^EAPPackages basicNew
I was trying to avoid tainting upstream code, but if I had to go there I'd rather replace the hardcoded "row := ODBCRow new: columns size." in method "ODBCResultSet>>fetchRow"
with "row := theReturnClassLikeODBCRow new: columns size."
and new method "ODBCStatement>>execute:args withReturnClass: theReturnClassLikeODBCRow" with existing method "ODBCStatement>>execute:args" changed to call "ODBCStatement>>execute:args withReturnClass: ODBCRow"

> > I had tried copyFrom: but some of the instance variables inherited from ODBCRow were not filled in, > > generating exceptions in some of the inherited methods. I had also considered "become:" but that didn't seem appropriate.
I'm somewhat puzzled that the copyFrom:/become: strategy (while an ugly approach imho) would fail though, do you think you could reduce it to a simple test using classes in the base image?
I've lost track of that code and I can't reproduce it so I must have been doing something wrong. However I had also been considering become: and copyFrom: independently and not as a combined strategy. Together they are sufficient. Thanks for the pointer Henry.

To close this out, here is what worked...

EAPPackages >> newFromConnection: connection
   | packages parent |
packages := (connection query: 'select * from t_package;') execute asTable. "comes back as an ODBCResultTable" self adoptInstance: packages. "no additional instance variables in subclass" packages do: [ :pkg || tmppkg | tmppkg := EAPPackage new copyFrom: pkg. tmppkg become: pkg ].
   ^packages.

<snip>
EAPPackages class >> newFromConnection: connection
   | packages parent |
packages := (connection query: 'select * from t_package;') execute asTable.
   self adoptInstance: packages.
packages do: [ :row | EAPPackage adoptInstance: row. ]. "this line replaced by copyFrom: & become:"
   ^packages.
<snip>

Cheers,
Henry
Thanks for your assistance.
cheers, Ben

Reply via email to