View previous topic :: View next topic |
Author |
Message |
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sun Jul 11, 2004 12:09 pm Post subject: IWriter confusion over types |
|
|
(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 |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sun Jul 11, 2004 12:16 pm Post subject: |
|
|
Can you post the enum (or whatever) for those constants please Chris? |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sun Jul 11, 2004 2:08 pm Post subject: |
|
|
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
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
- Kris
Last edited by kris on Mon Jul 12, 2004 12:20 am; edited 2 times in total |
|
Back to top |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Sun Jul 11, 2004 8:07 pm Post subject: |
|
|
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 |
|
|
csauls
Joined: 27 Mar 2004 Posts: 278
|
Posted: Mon Jul 12, 2004 9:03 am Post subject: |
|
|
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 |
|
|
csauls
Joined: 27 Mar 2004 Posts: 278
|
Posted: Mon Jul 12, 2004 9:06 am Post subject: |
|
|
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. _________________ Chris Nicholson-Sauls |
|
Back to top |
|
|
csauls
Joined: 27 Mar 2004 Posts: 278
|
Posted: Mon Jul 12, 2004 9:26 am Post subject: |
|
|
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 |
|
|
kris
Joined: 27 Mar 2004 Posts: 1494 Location: South Pacific
|
Posted: Mon Jul 12, 2004 11:26 am Post subject: |
|
|
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 |
|
|
|
|
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
|