Thread overview | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 27, 2008 Like getClass() | ||||
---|---|---|---|---|
| ||||
I'm trying to learn more about D object system (this is derived from a discussion I've had in #D), I have problems fully understanding some of the things the D docs say. This is a little Java program for reference: // Java code import java.util.*; interface FooBar {} class Foo implements FooBar {} class Bar implements FooBar {} public class test { public static void main(String[] args) { ArrayList<FooBar> things = new ArrayList<FooBar>(); things.add(new Bar()); things.add(new Foo()); for (FooBar thing : things) System.out.println(thing.getClass()); } } /* Output of the Java version: class Bar class Foo */ I have tried to translate it to D, and I have failed so far, this code compiles and runs, but I'd like to see the original class names in the output: // D code import std.stdio; interface FooBar {} class Foo : FooBar {} class Bar : FooBar {} void main() { FooBar[] things; things ~= new Bar; things ~= new Foo; foreach (thing; things) writefln(typeid(typeof(thing))); } /* Output of the D version: test.FooBar test.FooBar */ As you can see in D I am not able yet to find the class of the objects inserted into the 'things' array. Do you have suggestions? (I'd like to do this to sort the 'things' array according to the class). Bye and thank you, bearophile |
September 27, 2008 Re: Like getClass() | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | Sat, 27 Sep 2008 12:15:07 -0400,
bearophile wrote:
> // D code
> import std.stdio;
> interface FooBar {}
> class Foo : FooBar {}
> class Bar : FooBar {}
> void main() {
> FooBar[] things;
> things ~= new Bar;
> things ~= new Foo;
> foreach (thing; things)
> writefln(typeid(typeof(thing)));
> }
> /*
> Output of the D version:
> test.FooBar
> test.FooBar
> */
typeof() gives a static type of an object. But I was sure that thing.classinfo.name should have referred to the dynamic type name. Apparently it's not the case, it prints the same test.FooBar as in your test.
|
September 27, 2008 Re: Like getClass() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Gromov | Sergey Gromov: > typeof() gives a static type of an object. But I was sure that thing.classinfo.name should have referred to the dynamic type name. Apparently it's not the case, it prints the same test.FooBar as in your test. Thank you for your answer. So the question here is: is the information I need present at runtime somewhere? If the answer is true, then the problem is how to get it. I think this page of the docs may be improved with few graphical drawings of the data structures it talks about (with lines that show where the pointers point to at runtime in a simple example); such images can probably give all or most of the answers I was looking for: http://www.digitalmars.com/d/1.0/phobos/object.html Bye, bearophile |
September 27, 2008 Re: Like getClass() | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | bearophile wrote: > Sergey Gromov: >> typeof() gives a static type of an object. But I was sure that thing.classinfo.name should have referred to the dynamic type name. Apparently it's not the case, it prints the same test.FooBar as in your test. > > Thank you for your answer. > So the question here is: is the information I need present at runtime somewhere? > If the answer is true, then the problem is how to get it. obj.classinfo doesn't work the way you'd expect with an interface, but it works when you've got an object: writefln((cast(Object)thing).classinfo.name); This does look ugly, though. |
September 27, 2008 Re: Like getClass() | ||||
---|---|---|---|---|
| ||||
Posted in reply to torhu | torhu: > writefln((cast(Object)thing).classinfo.name); It works, thank you very much. Now I'll try to use it for the original purposes...... I'll have to work some more. I'll show here the results if I finish. > This does look ugly, though. Well, better ugly than not having any way to solve the problem :-) Bye, bearophile |
September 27, 2008 Re: Like getClass() | ||||
---|---|---|---|---|
| ||||
Posted in reply to torhu | I have solved my original problem :-) I show here the code for reference: This is the original Python code, that sorts a python list (array) of objects according to their class: class Circle: def __init__(self, x, y, radius): self.x = x self.y = y self.radius = radius def draw(self): print "Drawing Circle at (%s,%s) with radius %s" % (self.x, self.y, self.radius) class Square: def __init__(self, x, y, width): self.x = x self.y = y self.width = width def draw(self): print "Drawing Square at (%s,%s) with width %s" % (self.x, self.y, self.width) if __name__ == "__main__": order = [Circle, Square] # the order in which to draw the shapes shapes = [Circle(1,1,5), Square(2,4,3), Circle(3,3,7), Square(4,2,4)] shapes.sort(key=lambda s: order.index(s.__class__)) for shape in shapes: shape.draw() This is my best D translation so far, I am happy enough: import std.stdio: writefln; import d.func: sort, findPos; interface Shape { void draw(); } class Circle : Shape { float x, y, radius; this(float x, float y, float radius) { this.x = x; this.y = y; this.radius = radius; } void draw() { writefln("Drawing Circle at (%s,%s) with radius %s", x, y, radius); } } class Square : Shape { float x, y, width; this(float x, float y, float width) { this.x = x; this.y = y; this.width = width; } void draw() { writefln("Drawing Square at (%s,%s) with width %s", x, y, width); } } void main() { auto order = [Circle.classinfo, Square.classinfo]; // the order in which to draw the shapes auto shapes = [cast(Shape)(new Circle(1,1,5)), new Square(2,4,3), new Circle(3,3,7), new Square(4,2,4)]; shapes.sort((Shape s){ return findPos((cast(Object)s).classinfo, order); }); foreach (shape; shapes) shape.draw(); } It uses sort() and findPos(), but similar functions are probably present in Tango too, the first sorts an array according to a key function, and the second gives the index of an item into an iterable or -1 if absent. If the 'order' array becomes too much long it can of course be replaced by an associative array, that gives a faster lookup. Bye, bearophile |
September 27, 2008 Re: Like getClass() | ||||
---|---|---|---|---|
| ||||
Posted in reply to torhu | Sat, 27 Sep 2008 19:50:18 +0200,
torhu wrote:
> obj.classinfo doesn't work the way you'd expect with an interface, but it works when you've got an object:
>
> writefln((cast(Object)thing).classinfo.name);
Thanks for the tip! It seems like classinfo of an interface contains information about the most derived interface implemented in an object:
interface a {}
interface aa : a {}
class A : aa {}
void main() {
writefln((cast(a) new A).classinfo.name);
}
prints "test.aa". Though this functionality is of questionable usefulness (has anybody used it for something?) and besides it's broken:
interface a {}
interface aa : a {}
class A : a, aa {}
void main() {
writefln((cast(a) new A).classinfo.name);
}
prints "test.a" even though A implements the "aa" interface as well.
|
September 27, 2008 Re: Like getClass() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Gromov | Sergey Gromov wrote:
> Sat, 27 Sep 2008 19:50:18 +0200,
> torhu wrote:
>> obj.classinfo doesn't work the way you'd expect with an interface, but it works when you've got an object:
>>
>> writefln((cast(Object)thing).classinfo.name);
>
> Thanks for the tip! It seems like classinfo of an interface contains information about the most derived interface implemented in an object:
>
> interface a {}
> interface aa : a {}
> class A : aa {}
> void main() {
> writefln((cast(a) new A).classinfo.name);
> }
>
> prints "test.aa". Though this functionality is of questionable usefulness (has anybody used it for something?) and besides it's broken:
>
> interface a {}
> interface aa : a {}
> class A : a, aa {}
> void main() {
> writefln((cast(a) new A).classinfo.name);
> }
>
> prints "test.a" even though A implements the "aa" interface as well.
Since .classinfo is essentially a virtual call, and interface vtbls are filled from the class's vtbl, it shouldn't in theory be terribly difficult to change this. Of course, I'd have to check the dmd source to be sure.
|
September 28, 2008 Re: Like getClass() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Christopher Wright | Sat, 27 Sep 2008 19:21:56 -0400,
Christopher Wright wrote:
> Sergey Gromov wrote:
> > Sat, 27 Sep 2008 19:50:18 +0200,
> > torhu wrote:
> >> obj.classinfo doesn't work the way you'd expect with an interface, but it works when you've got an object:
> >>
> >> writefln((cast(Object)thing).classinfo.name);
> >
> > Thanks for the tip! It seems like classinfo of an interface contains information about the most derived interface implemented in an object:
> >
> > interface a {}
> > interface aa : a {}
> > class A : aa {}
> > void main() {
> > writefln((cast(a) new A).classinfo.name);
> > }
> >
> > prints "test.aa". Though this functionality is of questionable usefulness (has anybody used it for something?) and besides it's broken:
> >
> > interface a {}
> > interface aa : a {}
> > class A : a, aa {}
> > void main() {
> > writefln((cast(a) new A).classinfo.name);
> > }
> >
> > prints "test.a" even though A implements the "aa" interface as well.
>
> Since .classinfo is essentially a virtual call, and interface vtbls are filled from the class's vtbl, it shouldn't in theory be terribly difficult to change this. Of course, I'd have to check the dmd source to be sure.
I'd say it's a bug. Classinfo is for runtime class, and runtime class can never be an interface.
|
September 28, 2008 Re: Like getClass() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sergey Gromov | Sergey Gromov:
> I'd say it's a bug. Classinfo is for runtime class, and runtime class can never be an interface.
It seems all my questions in this newsgroup end with the discovery of another possible (and often real) bug ;-]
If it's not a bug, then I think a nicer syntax may be appreciable. In such thing Java may show some better syntax (well, better method name essentially, so better API and not really better syntax).
Bye and thank you,
bearophile
|
Copyright © 1999-2021 by the D Language Foundation