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