On Wed, Dec 28, 2011 at 12:08 PM, Ben Coman <[email protected]> wrote:
> Schwab,Wilhelm K wrote:
>
>> Ben,
>>
>> That's a lot to read. If I'm getting the message, you want to subclass
>> ODBCRow and are concerned about Metacello.
>>
> Point taken. In hindsight too much background info and a mixed message.
> Actually it wasn't not a question about Metacello - though my other recent
> mention of ConfigurationOfODBC was. I only mentioned ConfigurationOfODBC
> here to distinguish it from the ODBC in DBXTalk
Just in case of interest, in DBXTalk you CAN access not only by index but
by name.
rawValueAt: anIndex
"It returns the value of the raw at the specified index. No conversion
is here, so all values will be String"
^rawValues at: anIndex
rawValueNamed: aString
"It returns the value of the raw with the specified name. No conversion
is here, so all values will be String"
^self rawValueAt: (self columnIndex: aString)
And you can also get the values and convert them to smalltalk objects:
valueAt: anIndex
"It returns the value of the raw at the specified index. Each string
returned from openDBX will be converted, if supported, to Squeak types"
^self convertValueAt: anIndex
valueNamed: aString
"It returns the value of the raw with the specified name. Each string
returned from openDBX will be converted, if supported, to Squeak types"
^self convertValueAt: (self columnIndex: aString).
Cheers
> - and in hindsight that is not the core question. The short version is
> "how do I change the class of existing object into one of its subclasses".
> I've got it working, but not if I add an instance variable to the subclass.
>
> FWIW, I suspect I would make some type of wrapper class for the rows
>> rather than subclass - the goal being to strive for uses-a vs. is-a.
>>
>>
> I had considered that briefly but was concerned that the wrapped class
> needed to understand every message that the wrapped-class understood. I
> wanted to use the existing ODBCResultTable which holds the ODBCRows to
> contain my new subclass of ODBCRow. I will think further about this.
>
> Idealistically (and perhaps naively) yours,
>>
>>
> More than I would know. Thanks for your time. -Ben
>
> Bill
>>
>>
>> ______________________________**__________
>> From:
>> pharo-project-bounces@lists.**gforge.inria.fr<[email protected]>[
>> pharo-project-bounces@lists.**gforge.inria.fr<[email protected]>]
>> on behalf of Ben Coman [[email protected]]
>> Sent: Tuesday, December 27, 2011 11:46 PM
>> To:
>> [email protected].**inria.fr<[email protected]>
>> Subject: [Pharo-project] changing the class of an existing object to a
>> subclass
>>
>> greetings all,
>>
>> I am using ConfigurationOfODBC in Pharo 1.3. I have had success with
>> getting an ODBCResultTable(**OrderedCollection) containing ODBCRow
>> containing about 30 fields. By default the fields are accessed by "row
>> at: #fieldName" but I wanted to add some convenience methods to instead
>> go "row fieldName." My searching and experimentation led me to
>> subclassing ODBCRow as EAPPackage and then using "adoptInstance:" on
>> each ODBCRow to convert it to the subclass. This was to avoid having to
>> having to understand and change any of the ConfigurationOfODBC code. 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.
>>
>> Using "adoptInstance:" worked fine until I added a new instance variable
>> to EAPPackage. Subsequently for "<primitive: 160 error: ec>", ec =
>> #'bad receiver'. The "adoptInstance:" method comment says it follows
>> the same rules as "primitiveChangeClassTo:" (yet note that
>> "primitiveChangeClassTo:" never worked)
>> The "primitiveChangeClassTo:" method comment says "The primitive will
>> fail in most cases that you think might work [...] The facility is
>> really provided for certain, very specific applications (mostly related
>> to classes changing shape) and not for casual use" so I wondered if
>> there was another way to achieve this.
>>
>> The full code is hopefully not too long to include for reference below.
>> The use of "adoptInstance:" in the last section listed.
>> ------
>> ODBCRow subclass: #EAPPackage
>> instanceVariableNames: 'parent' "note adoptInstance works without
>> this instance variable, and not with"
>> classVariableNames: ''
>> poolDictionaries: ''
>> category: 'BTC-EA-Explore'
>> ------
>> EAPPackage >> name
>> ^ self at: #Name
>> ------
>> ODBCResultTable subclass: #EAPPackages
>> instanceVariableNames: ''
>> classVariableNames: ''
>> poolDictionaries: ''
>> category: 'BTC-EA-Explore'
>> ------
>> EAPPackages class >> newFromConnection: connection
>> | packages parent |
>> packages := (connection query: 'select * from t_package;') execute
>> asTable.
>> self adoptInstance: packages.
>>
>> packages do: [ :row | EAPPackage adoptInstance: row. ].
>>
>> ^packages.
>> ------
>> In a Workspace I successfully evaluate the following three lines without :
>> connection := ODBCConnection dsn: 'CIM' user: '' password: ''.
>> packages := EAPPackages newFromConnection: connection.
>> connection close.
>> ------
>>
>> I found the ODBCRow instance creation to ODBCResultSet>>fetchRow. One
>> alternative I've considered is to somehow pass through a custom
>> SomeClass in a variable to replace the hard reference to ODBCRow - but I
>> don't want to chase back all the cascading call references.
>>
>> Is there another way to change an existing object to another class, such
>> that it can be specialised with both additional methods and instance
>> variables?
>> I would appreciate any pointers.
>>
>> regards, Ben
>>
>>
>>
>>
>>
>
>
>
--
Mariano
http://marianopeck.wordpress.com