FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

IWriter confusion over types

 
Post new topic   Reply to topic     Forum Index -> Mango
View previous topic :: View next topic  
Author Message
kris



Joined: 27 Mar 2004
Posts: 1494
Location: South Pacific

PostPosted: Sun Jul 11, 2004 12:09 pm    Post subject: IWriter confusion over types Reply with quote

(originally posted by csauls, and moved into a seperate thread for the sake of clarity)
Quote:

csauls wrote:
I'm going to hijack your thread for a moment. Smile You may want to consider adding:

alias DisplayWriter.put put;

to the TextWriter class. For some reason, DMD0.94 wants to match all calls to TextWriter's put(IWritable). It might be a bug in DMD's override but just adding the alias makes things work. Either that or I'm doing something fishy?


I suspect what might be happening is that you trying to put() a type that's not recognized by the set of put() prototypes in IWriter (or something like that). If dmd doesn't find a matching prototype it uses one of the others as "an example" in the error message; this can be really confusing.

For example: you will get a bogus error message if you try to put (int[]), since arrays of integers are not directly supported ...

Code:
TextWriter t = new TextWriter (...);
int[10] x;

t.put (x);

function opShl (bit x) does not match argument types (int[10])
cannot implicitly convert int[10] to IWritable


Which data type are you using?

csauls wrote:
The following will generate that error:
Code:
void writeVar(Var var, TextWriter tw) {
  switch (var.type) {
    case CLEAR:
      tw.put(NCLEAR); // fails.  NCLEAR is int.
      break;

    case INT:
      tw.put(NINT).put(var.i);
      break;

    case FLOAT:
      tw.put(NFLOAT).put(var.f);
      break;

    case STR:
      tw.put(NSTR).put(var.s);
      break;

    case OBJ:
      tw.put(NOBJ).put(var.i);
      break;

    case ERR:
      tw.put(NERR).put(var.i);
      break;

    case LIST:
      tw.put(NLIST).put(var.l.length);
      foreach (inout Var x; var.l) {
        writeVar(x, tw);
      }
      break;
  }
}

_________________
C. Sauls
Invironz
Back to top
View user's profile Send private message
kris



Joined: 27 Mar 2004
Posts: 1494
Location: South Pacific

PostPosted: Sun Jul 11, 2004 12:16 pm    Post subject: Reply with quote

Can you post the enum (or whatever) for those constants please Chris?
Back to top
View user's profile Send private message
kris



Joined: 27 Mar 2004
Posts: 1494
Location: South Pacific

PostPosted: Sun Jul 11, 2004 2:08 pm    Post subject: Reply with quote

heh heh!

I bet if you were to change
Code:
void writeVar(Var var, TextWriter tw)

to
Code:
void writeVar(Var var, IWriter tw)

it would work just fine.

<rant>
Dmd definately has some issues around method inheritence when the basic name is the same. I mean, method resolution does not do signature matching when the method names match; patently ridiculous to my mind. The whole alias hack for working around it just introduces more warts, and doesn't even work in anything but the simplest cases. Hey! Perhaps one could get a patent on that Confused

If the Interface approach makes it work, then more power to Interfaces. At least those work intuitively, except when trying to inherit interface methods from a superclass (that's a different story, although it appears related to the whole "vague matching" and "alias hack" crapshoot).
</rant>

BTW Chris;

One of the benefits of D versus C can become apparent in what you are doing here. If you were to make Var an abstract base-class and give it a writeMe(IWriter) method, then each variation on the theme would become a subclass of that: IntVar, ListVar etc. Then you'd just need to call writeMe() on any instance and it would do the right thing. This would be especially noticeable in ListVar, where its writeMe() would polymorphically invoke each of its Var[] list members via a list[i].writeMe(writer), or equivalent.

This approach is supported by mango.io such that if a class implements the IWritable interface, it can be used directly with any IWriter. For example, you could just do a TextWriter.put(ListVar). All those maintenance issues related to enum and switch() simply disappear, and some would argue that it executes faster as a side benefit.

I did a similar struct/switch thing myself recently (I claim it was a tired mistake); luckily Eric pointed out the error of my ways before too many others shot me down Embarassed

- Kris


Last edited by kris on Mon Jul 12, 2004 12:20 am; edited 2 times in total
Back to top
View user's profile Send private message
kris



Joined: 27 Mar 2004
Posts: 1494
Location: South Pacific

PostPosted: Sun Jul 11, 2004 8:07 pm    Post subject: Reply with quote

kris wrote:
I bet if you were to change
Code:
void writeVar(Var var, TextWriter tw)

to
Code:
void writeVar(Var var, IWriter tw)

it would work just fine.

It compiles cleanly if you specify tw as either IWriter or as the base-class Writer. It sucks, I know. If enough people complain loudly, perhaps Walter will reconsider ...
Back to top
View user's profile Send private message
csauls



Joined: 27 Mar 2004
Posts: 278

PostPosted: Mon Jul 12, 2004 9:03 am    Post subject: Reply with quote

I'm going to try changing the argument to IWriter here in a minute and see if that works.. I am thinking of making a Var a class much as you suggest (its currently a struct), and putting its read/write methods inside it... But, I don't think the IntVar, ListVar, etc thing will work very well in this case, as Var is representing the weakly-typed variables of Neo's scripting language. The Var struct is actually a trick I'm borrowing from the original Lambda server, because I just can't see any better way of going about it.

Anyway, since you asked and it might yet be useful, the enums and the Var struct itself:
Code:

enum {
  INT   = 0,
  OBJ   = 1,
  STR   = 2,
  ERR   = 3,
  LIST  = 4,
  CLEAR = 5,
  FLOAT = 9,
}

enum {
  NCLEAR  = 0,
  NINT    = 1,
  NFLOAT  = 2,
  NSTR    = 3,
  NOBJ    = 4,
  NERR    = 5,
  NLIST   = 6
}

struct Var {
  int type;

  union {
    int     i;
    float   f;
    char[]  s;
    Var[]   l;
  }
}

_________________
Chris Nicholson-Sauls
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
csauls



Joined: 27 Mar 2004
Posts: 278

PostPosted: Mon Jul 12, 2004 9:06 am    Post subject: Reply with quote

Just thought I'd mention that I've also been considering writing my own Writer class instead, as it would make it easier to re-use the same database modules between the Neo server and the Neo converter. (Just use a sub-class of the Writer for the converter, the normal one in the server.) That would be a 100? solution to the issue, but I still think its a bug so I'm gonna make it work this way first. Wink
_________________
Chris Nicholson-Sauls
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
csauls



Joined: 27 Mar 2004
Posts: 278

PostPosted: Mon Jul 12, 2004 9:26 am    Post subject: Reply with quote

Son of a gun... just changing the arguments to IWriter fixes it. I had to repeat the change in several other places where the TextWriter gets tossed around, but it does indeed work. Incredable. I think I'll put this in storage now and go on with the new plan of a custom Writer.
_________________
Chris Nicholson-Sauls
Back to top
View user's profile Send private message AIM Address Yahoo Messenger
kris



Joined: 27 Mar 2004
Posts: 1494
Location: South Pacific

PostPosted: Mon Jul 12, 2004 11:26 am    Post subject: Reply with quote

csauls wrote:
Son of a gun... just changing the arguments to IWriter fixes it. I had to repeat the change in several other places where the TextWriter gets tossed around, but it does indeed work. Incredable. I think I'll put this in storage now and go on with the new plan of a custom Writer.

Erratic behaviour from the compiler is frustrating at best. This particular issue seems to get very little attention, along with all the other namespace collisions. Glad it worked out for you though, and rolling a custom Writer subclass is definately a good idea. I tend to pass everyting around as the Interface itself, until I actually need the specialization of a subclass. Probably why (thus far) I've managed to avoid these collision issues internally within Mango. I did bump into it yesterday though, after specializing the StdioWriter; that caused exactly the kind of problem you initially brought up ...
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> Mango All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group