On 4 December 2017 at 00:10, Luke Gorrie <[email protected]> wrote: > Howdy, > > I have some Smalltalk objects that represent external data and I am looking > for a neat way to access them. > > The data that I am dealing with is C binary objects described by DWARF > schemas. So I will load a type declaration like this: > > struct outer { > struct inner { > int a, b; > }; > }; > > and then I will want to be able to write convenient expressions like: > > aStruct outer inner a + aStruct outer inner b > > I have implemented this already but I am not sure that I took the right > approach.
Seems like a reasonable approach, except difficulties with the broadness of your DSL domain (as you've found.) > I have implemented these accessors like #outer #inner #a #b via a > messageNotUnderstood: method that looks into the object, so that 'aStruct > outer' is equivalent to 'aStruct field: #outer'. My concern is that the > names of the C struct fields can collide with existing Smalltalk methods and > then I will get totally unexpected results. > > Is there a canonical solution to this problem? > > The first idea I have is to add a bit of syntatic sugar, like to write > 'aStruct _outer _inner _a' where the leading underscore avoids method name > collisions and is then stripped off in messageNotUnderstood. That doesn't > seem especially elegant though. > > I can't quite bring myself to write verbose things like > > ((aStruct child: #outer) child: #inner) child: #a > > An easy improvement might be to subclass your DwarfStruct from ProtoObject rather than Object to significantly reduce the surface area of name clashes. * https://github.com/pharo-project/pharo/blob/development/src/Kernel/ProtoObject.class.st But I've not worked much with ProtoObject so I'm not sure what difficulties that might bring. In particular, can anyone comment on extra requirements to support object display in GT Inspector? A naming clash with the remaining ProtoObject methods seems extremely unlikely, and the easiest path would be to just guard against loading such structs. DwarfStruct>>loadStructure ... nameClashes := ProtoObject methodNames. self fieldnames do: [ :f | (nameClashes includes: f) ifTrue: [ self error: 'Seriously!? Your trying awful hard to break me' ] ] Just for the fun of it(!?) you might even try reducing that surface area by renaming that just in your personal Images by renaming ProtoObject methods. (Actually thats any interesting experiment I'll have to try later when I've got Pharo in front of me.) The only other thing I can think of is, presuming you've got a single class (e.g. DwarfStruct) holding the structure as data. for each loaded structure, generate "DwarfStruct subclass: CStruct1" and CStruct1>>fieldname so that method lookup stops at the first class and doesn't run all the way up the class hierarchy. But that would still be susceptible to breaking the system by overloading messages critical to system operation. cheers -ben
