digitalmars.D.learn - Unqualified class name
- Jeremy T. Gibson (14/14) Aug 21 2021 I saw this thread --
- =?UTF-8?Q?Ali_=c3=87ehreli?= (13/16) Aug 21 2021 I've been reminded of __traits(identifier) on this forum just yesterday:
- Jeremy T. Gibson (2/3) Aug 21 2021 That works perfectly! Thanks. =)
- jfondren (16/19) Aug 21 2021 This is exactly the solution you linked to in your first post,
- =?UTF-8?Q?Ali_=c3=87ehreli?= (18/40) Aug 21 2021 typeof(this));
- jfondren (24/39) Aug 21 2021 That's not enough to make runtime dispatch out of static dispatch:
- jfondren (36/42) Aug 21 2021 https://dlang.org/phobos/object.html#.TypeInfo_Class.name is all
- Jeremy T. Gibson (12/28) Aug 21 2021 Parsing was always an option, but anytime I come across a
I saw this thread -- https://forum.dlang.org/post/hdkvezicxfvehbtvjkfu forum.dlang.org -- which works at compile time (although templating seems like overkill for my purpose), but is there a simple way to get the unqualified name of a class at runtime without having to pass it through std.format? `typeid(class).name` always yields the full classname, including its module information (i.e., "modulename.classname"), where I only want "classname" on its own. I'm currently using manually-assigned literals to store the name of each class, which seems... wrong. ;-) If it matters or makes things simpler, the class is attempting to report its own name in one of its own methods, rather than an external function attempting to deduce the name of an arbitrary object at runtime.
Aug 21 2021
On 8/21/21 10:33 AM, Jeremy T. Gibson wrote:`typeid(class).name` always yields the full classname, including its module information (i.e., "modulename.classname"), where I only want "classname" on its own.I've been reminded of __traits(identifier) on this forum just yesterday: import std.stdio; class Coo { string name() const { return __traits(identifier, typeof(this)); } } void main() { auto c = new Coo(); writeln(c.name()); } Ali
Aug 21 2021
On Saturday, 21 August 2021 at 18:27:34 UTC, Ali Çehreli wrote:return __traits(identifier, typeof(this));That works perfectly! Thanks. =)
Aug 21 2021
On Saturday, 21 August 2021 at 21:13:58 UTC, Jeremy T. Gibson wrote:On Saturday, 21 August 2021 at 18:27:34 UTC, Ali Çehreli wrote:This is exactly the solution you linked to in your first post, and found wanting. ```d class Whoami { string name() { return __traits(identifier, typeof(this)); } } class AnotherOne : Whoami { } unittest { assert((new Whoami).name == "Whoami"); assert((new AnotherOne).name == "Whoami"); } ```return __traits(identifier, typeof(this));That works perfectly! Thanks. =)
Aug 21 2021
On 8/21/21 2:48 PM, jfondren wrote:On Saturday, 21 August 2021 at 21:13:58 UTC, Jeremy T. Gibson wrote:d=20On Saturday, 21 August 2021 at 18:27:34 UTC, Ali =C3=87ehreli wrote:=20 This is exactly the solution you linked to in your first post, and foun==C2=A0=C2=A0=C2=A0 return __traits(identifier, typeof(this));That works perfectly!=C2=A0 Thanks. =3D)wanting. =20 ```d class Whoami { =C2=A0=C2=A0=C2=A0 string name() { =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return __traits(identifier,=typeof(this));=C2=A0=C2=A0=C2=A0 } } class AnotherOne : Whoami { } =20 unittest { =C2=A0=C2=A0=C2=A0 assert((new Whoami).name =3D=3D "Whoami"); =C2=A0=C2=A0=C2=A0 assert((new AnotherOne).name =3D=3D "Whoami"); } ```I did not read the linked thread but a "this template parameter" seems=20 to work in this case: class Whoami { string name(this This)() const { return __traits(identifier, This); } } class AnotherOne : Whoami { } unittest { assert((new Whoami).name =3D=3D "Whoami"); assert((new AnotherOne).name =3D=3D "AnotherOne"); } void main() { } Ali
Aug 21 2021
On Sunday, 22 August 2021 at 00:18:18 UTC, Ali Çehreli wrote:I did not read the linked thread but a "this template parameter" seems to work in this case: class Whoami { string name(this This)() const { return __traits(identifier, This); } } class AnotherOne : Whoami { } unittest { assert((new Whoami).name == "Whoami"); assert((new AnotherOne).name == "AnotherOne"); } void main() { } AliThat's not enough to make runtime dispatch out of static dispatch: ```d class Whoami { string name(this This)() const { return __traits(identifier, This); } string rtname() const { import std.path : extension; return typeid(this).name.extension[1 .. $]; } } class AnotherOne : Whoami { } unittest { import std.algorithm : map, equal; auto list = [new Whoami, new AnotherOne]; assert(list.map!(o => o.name).equal(["Whoami", "Whoami"])); assert(list.map!(o => o.rtname).equal(["Whoami", "AnotherOne"])); } ``` The next stage of complication is to have compiled library code that loops over Whoami[] getting some subtypes of Whoami that were defined unknowable to the library.
Aug 21 2021
On Saturday, 21 August 2021 at 17:33:51 UTC, Jeremy T. Gibson wrote:is there a simple way to get the unqualified name of a class at runtime without having to pass it through std.format? `typeid(class).name` always yields the full classname, including its module information (i.e., "modulename.classname"), where I only want "classname" on its own.https://dlang.org/phobos/object.html#.TypeInfo_Class.name is all you have there, and it's just a string, so the simple way is to manipulate the string. This seems a bit silly but I'm not worried about VMS 2.0 coming along and changing how extensions work ("nodot".extension == "" however, so if module-less classes are possible then this would fail with a RangeError): ```d class Whoami { string report() { import std.path : extension; return "class: " ~ typeid(this).name.extension[1..$]; } } class AnotherOne : Whoami {} unittest { assert((new Whoami).report == "class: Whoami"); assert((new AnotherOne).report == "class: AnotherOne"); } string unqualified(string name) { import std.string : lastIndexOf; import std.algorithm : min; const i = name.lastIndexOf('.'); return i == -1 ? name : name[min(i+1, $) .. $]; } unittest { assert(typeid(new Whoami).name.unqualified == "Whoami"); assert(typeid(new AnotherOne).name.unqualified == "AnotherOne"); assert("".unqualified == ""); assert("x".unqualified == "x"); assert("x.".unqualified == ""); } ```
Aug 21 2021
On Saturday, 21 August 2021 at 18:45:07 UTC, jfondren wrote:On Saturday, 21 August 2021 at 17:33:51 UTC, Jeremy T. Gibson wrote:is there a simple way to get the unqualified name of a class at runtime without having to pass it through std.format? `typeid(class).name` always yields the full classname, including its module information (i.e., "modulename.classname"), where I only want "classname" on its own.https://dlang.org/phobos/object.html#.TypeInfo_Class.name is all you have there, and it's just a string, so the simple way is to manipulate the string.string unqualified(string name) { import std.string : lastIndexOf; import std.algorithm : min; const i = name.lastIndexOf('.'); return i == -1 ? name : name[min(i+1, $) .. $];Parsing was always an option, but anytime I come across a solution where parsing/formatting seems to be the answer, it always feels more hacky than a genuine solution. Hacks can be fine, especially in low-frequency code like the stuff I'm revisiting this month, but I always prefer direct library-based or language-based solutions whenever humanly possible. Dlang's reference docs unfortunately assume a level of expertise with the language (especially, expertise with code generation and compiler specs) that makes it much harder for me to "ask the right questions" when I'm searching: I'm really not much of a programmer. Heh.
Aug 21 2021