Type conversion in accessors?

Discussion of Common Lisp
Post Reply
smcnamara
Posts: 11
Joined: Fri Oct 10, 2008 2:48 pm

Type conversion in accessors?

Post by smcnamara » Thu Aug 11, 2011 8:31 pm

I'm struggling a little bit with figuring out what the lispy way to handle a problem with accessor type-conversion, and am hoping someone can point me in the right direction.

I'm parsing a stream of delimited strings. The protocol specifies that the first string is an integer value indicating the type of the message, followed by some arbitrary number of delimited strings (determined by the message type.)

A message might be defined as:

Code: Select all

MESSAGE_TYPE: 1 (LOCATION-OVERVIEW)
   string: name
   integer: location-id
   double: resource-rating
And on the wire, the stream (shown with 2 messages of TYPE:1) would look like:

Code: Select all

1@Haymarket@[email protected]@1@Joliet@[email protected]@...
I've modeled the various structures that can be received on the wire, however different messages may populate different fields in a structure. Currently, I've got a bunch of ugly code that does string processing and type conversion as the stream is parsed, but this is ugly and cumbersome. I'd much prefer to put the type conversion around the slots of the class and do the conversion when setting the value. Unfortunately I'm having a hard time figuring out exactly how to make this happen.

In a nutshell, instead of having code that does something like:

Code: Select all

(let ((token (parse-next-token my-stream))
   (setf (slot-value obj 'resource-rating) (read-from-string token))))
I'd prefer to say:

Code: Select all

(let ((token (parse-next-token my-stream))
   (setf (slot-value obj 'resource-rating) token))
I'm feeling like there may be a way to do this with slot accessors and :before or :around methods, but am not seeing the path clearly (and could certainly be off in the weeds.)

Any pointers here are appreciated.

**Edit**

As a follow-up, I realize I can use (read-from-string) to get automatic conversion for many cases, but there is some strange behavior in the system that requires special handling. For instance, some messages have boolean fields where NULL=false and *anything*=true, while other messages have boolean fields where 0=false and *anything-else*=true, while yet others have 1=true, and *anything-else*=false. :shock:

Yes, bask in the horribleness, but that's what I'm stuck with.

ramarren
Posts: 613
Joined: Sun Jun 29, 2008 4:02 am
Location: Warsaw, Poland
Contact:

Re: Type conversion in accessors?

Post by ramarren » Thu Aug 11, 2011 11:40 pm

smcnamara wrote:Currently, I've got a bunch of ugly code that does string processing and type conversion as the stream is parsed, but this is ugly and cumbersome. I'd much prefer to put the type conversion around the slots of the class and do the conversion when setting the value. Unfortunately I'm having a hard time figuring out exactly how to make this happen.
Slot accessors are not, in general, in any way special, they are just standard methods. You can just define a primary method as an accessor and use (setf (slot-value ...)) internally.

But I don't think that is the best approach. Determining types should be part of the parsing process. What you probably need to create a descriptions of message formats and then use it to drive the parser, rather than create custom code for every message, as it seems you are doing. It is hard to tell without more details.

Post Reply