www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to use ".stringof" to get the value of a variable and not the name

reply rempas <rempas tutanota.com> writes:
Let's see the following example:

```d
import std.stdio;

static foreach(i; 0 .. 10) {
   mixin(create_fn!(i.stringof));
}

enum create_fn(string num) = `
   void function_`~ num ~`() { writeln("Hello from function `~ num 
~`!"); }
`;

void main() {
   function10();
}
```

I'm trying to create a series of function. There will be ten of 
them, and they will be called `function_0`, `function_1`, etc. 
However, in my example, "stringof" returns the character "i" 
itself and turns that into a string instead of getting its actual 
value (number).

Any ideas how I can achieve what I'm trying to achieve?
Oct 09 2023
next sibling parent reply mw <m g.c> writes:
use:

import std.conv;

... i.to!string ...



```
import std.stdio;
import std.conv;

static foreach(i; 0 .. 10) {
   mixin(create_fn!(i.to!string));
}

enum create_fn(string num) = `
   void function_`~ num ~`() { writeln("Hello from function `~ num 
~`!"); }
`;

void main() {
   function_9();
}

```


$ dmd -c gen_fun_i.d
$ nm gen_fun_i.o  | grep function_
0000000000000000 W _D9gen_fun_i10function_0FZv
0000000000000000 W _D9gen_fun_i10function_1FZv
0000000000000000 W _D9gen_fun_i10function_2FZv
0000000000000000 W _D9gen_fun_i10function_3FZv
0000000000000000 W _D9gen_fun_i10function_4FZv
0000000000000000 W _D9gen_fun_i10function_5FZv
0000000000000000 W _D9gen_fun_i10function_6FZv
0000000000000000 W _D9gen_fun_i10function_7FZv
0000000000000000 W _D9gen_fun_i10function_8FZv
0000000000000000 W _D9gen_fun_i10function_9FZv

$ dmd gen_fun_i.d
$ ./gen_fun_i
Hello from function 9!


On Monday, 9 October 2023 at 16:33:32 UTC, rempas wrote:
 Let's see the following example:

 ```d
 import std.stdio;

 static foreach(i; 0 .. 10) {
   mixin(create_fn!(i.stringof));
 }

 enum create_fn(string num) = `
   void function_`~ num ~`() { writeln("Hello from function `~ 
 num ~`!"); }
 `;

 void main() {
   function10();
 }
 ```

 I'm trying to create a series of function. There will be ten of 
 them, and they will be called `function_0`, `function_1`, etc. 
 However, in my example, "stringof" returns the character "i" 
 itself and turns that into a string instead of getting its 
 actual value (number).

 Any ideas how I can achieve what I'm trying to achieve?
Oct 09 2023
parent reply rempas <rempas tutanota.com> writes:
On Monday, 9 October 2023 at 16:42:38 UTC, mw wrote:
 use:

 import std.conv;

 [...]
Damn, sorry, forgot to mention. I cannot use Phobos.
Oct 09 2023
parent reply mw <m g.c> writes:
On Monday, 9 October 2023 at 16:51:31 UTC, rempas wrote:
 On Monday, 9 October 2023 at 16:42:38 UTC, mw wrote:
 use:

 import std.conv;

 [...]
Damn, sorry, forgot to mention. I cannot use Phobos.
but you `import std.stdio;`? Or copy the std/conv.d over to your build, or copy / write a toString(int) function yourself, which is compile-time callable.
Oct 09 2023
parent reply rempas <rempas tutanota.com> writes:
On Monday, 9 October 2023 at 16:53:55 UTC, mw wrote:
 but you `import std.stdio;`?

 Or copy the std/conv.d over to your build,

 or copy / write a toString(int) function yourself, which is 
 compile-time callable.
I do on that example just to use "write". It wouldn't be necessary, but I just included it. My normal project does not use Phobos.
Oct 09 2023
next sibling parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Monday, 9 October 2023 at 16:55:41 UTC, rempas wrote:
 On Monday, 9 October 2023 at 16:53:55 UTC, mw wrote:
 but you `import std.stdio;`?

 Or copy the std/conv.d over to your build,

 or copy / write a toString(int) function yourself, which is 
 compile-time callable.
I do on that example just to use "write". It wouldn't be necessary, but I just included it. My normal project does not use Phobos.
You could just add your own int to string I guess?
Oct 09 2023
parent reply rempas <rempas tutanota.com> writes:
On Monday, 9 October 2023 at 17:42:48 UTC, Imperatorn wrote:
 You could just add your own int to string I guess?
That will be a good idea! I'll do it in the future if that is the case, as it's not important, and I want to finish my job. Thank you and have a great day!
Oct 09 2023
parent reply Hipreme <msnmancini hotmail.com> writes:
On Monday, 9 October 2023 at 18:25:15 UTC, rempas wrote:
 On Monday, 9 October 2023 at 17:42:48 UTC, Imperatorn wrote:
 You could just add your own int to string I guess?
That will be a good idea! I'll do it in the future if that is the case, as it's not important, and I want to finish my job. Thank you and have a great day!
My engine has its own implementation of toString(long), which does not have dependency with the C runtime: https://github.com/MrcSnm/HipremeEngine/blob/master/modules/util/source/hip/util/conv.d#L180C1-L208C2 I have reimplemented the entire conv module since it is one of mostly used module and it pulled down a lot of things, so, with my util module I was able to make my program much smaller too.
Oct 10 2023
parent reply rempas <rempas tutanota.com> writes:
On Tuesday, 10 October 2023 at 11:46:38 UTC, Hipreme wrote:
 My engine has its own implementation of toString(long), which 
 does not have dependency with the C runtime:

 https://github.com/MrcSnm/HipremeEngine/blob/master/modules/util/source/hip/util/conv.d#L180C1-L208C2

 I have reimplemented the entire conv module since it is one of 
 mostly used module and it pulled down a lot of things, so, with 
 my util module I was able to make my program much smaller too.
Thank you for the idea! However, your code used Phobos which I don't want to use so it will not do.
Oct 10 2023
parent reply bachmeier <no spam.net> writes:
On Tuesday, 10 October 2023 at 13:55:44 UTC, rempas wrote:
 On Tuesday, 10 October 2023 at 11:46:38 UTC, Hipreme wrote:
 My engine has its own implementation of toString(long), which 
 does not have dependency with the C runtime:

 https://github.com/MrcSnm/HipremeEngine/blob/master/modules/util/source/hip/util/conv.d#L180C1-L208C2

 I have reimplemented the entire conv module since it is one of 
 mostly used module and it pulled down a lot of things, so, 
 with my util module I was able to make my program much smaller 
 too.
Thank you for the idea! However, your code used Phobos which I don't want to use so it will not do.
Which part uses Phobos? The linked function compiles without importing anything.
Oct 10 2023
parent rempas <rempas tutanota.com> writes:
On Tuesday, 10 October 2023 at 16:11:57 UTC, bachmeier wrote:
 Which part uses Phobos? The linked function compiles without 
 importing anything.
Actually, you are right. I didn't give a lot of thought to it, as there is the line `char[] ret = new char[](length);` but I can replace it with an external buffer. Anyway, I'm not trying to do that anymore, and I will also create my own `int_to_string` method in the future but thanks for pointing it out!
Oct 13 2023
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, October 9, 2023 10:55:41 AM MDT rempas via Digitalmars-d-learn 
wrote:
 On Monday, 9 October 2023 at 16:53:55 UTC, mw wrote:
 but you `import std.stdio;`?

 Or copy the std/conv.d over to your build,

 or copy / write a toString(int) function yourself, which is
 compile-time callable.
I do on that example just to use "write". It wouldn't be necessary, but I just included it. My normal project does not use Phobos.
The language does not have a way to convert variables to strings. The normal solution for that is to use Phobos. The closest to a built-in solution would be toString on classes and structs, but structs don't necessarily have a toString. Rather, in many cases, Phobos does introspection on the struct to figure out how to convert the struct's members to a string if no toString is present (which isn't necessarily pretty but generally works well for debug output). Anyone looking to be able to do that sort of thing without Phobos is either going to need to reimplement what Phobos does themselves or use a third party library that already does that. std.conv.to provides the ability to convert between types in general based on their constructors, opCast member functions, and toString (if the user-defined type has one). So, it's able to convert pretty much any type to a string using to!string. std.format.format is then D's equivalent to snprintf, and it's able to convert pretty much any type to a string. I'm not sure if it uses to!string internally though. Regardless, if you want to be able to convert an arbitrary variable to a string without using Phobos, you basically have to reimplement all of that yourself (or at least as much as you need to do whatever it is that you're doing). C functions like snprintf can be used to convert the primitive types (meaning that you wouldn't have to implement something like the mess that is converting floating points to string), but for user-defined types that don't have toString, you'd basically be forced to do the kind of type introspection that Phobos does to produce a string from each of the member variables. It's possible that there's library somewhere that doesn't rely on Phobos that provides some of the same functionality (e.g. for the guys looking to use -betterC as a long term solution rather than just as a porting tool), but the language itself doesn't have that kind of functionality. Now, if what you're looking to do is to specifically convert an integer to a string at compile time (which means that snprintf wouldn't be a solution, since you can't call C functions during CTFE) rather than converting variables in general to string, then it shouldn't be hard to write a simple function that converts from an integer to a string. So, if that's all that you're looking to do, it shouldn't be hard to avoid Phobos. However, you're still going to need to implement it yourself. - Jonathan M Davis
Oct 09 2023
parent rempas <rempas tutanota.com> writes:
On Monday, 9 October 2023 at 17:52:58 UTC, Jonathan M Davis wrote:
 The closest to a built-in solution would be toString on classes 
 and structs, but structs don't necessarily have a toString. 
 Rather, in many cases, Phobos does introspection on the struct 
 to figure out how to convert the struct's members to a string 
 if no toString is present (which isn't necessarily pretty but 
 generally works well for debug output). Anyone looking to be 
 able to do that sort of thing without Phobos is either going to 
 need to reimplement what Phobos does themselves or use a third 
 party library that already does that.

 [...]
Thank you for the info. Unfortunately, while my project uses libc, I try to get rid of it as well, so it will also not do. I may create a function in the future myself. Thanks a lot for your time and I hope you have a beautiful day!
Oct 09 2023
prev sibling next sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Monday, 9 October 2023 at 16:33:32 UTC, rempas wrote:
 I'm trying to create a series of function. There will be ten of 
 them, and they will be called `function_0`, `function_1`, etc. 
 However, in my example, "stringof" returns the character "i" 
 itself and turns that into a string instead of getting its 
 actual value (number).

 Any ideas how I can achieve what I'm trying to achieve?
Great masters generally warn to stay away from stringof. Please do not use it as much as possible. The following code snippet will be useful to you: ```d alias CN = __traits(allMembers, CardinalNumbers); static foreach(i; CN) { mixin(create_fn!(i[1])); } enum create_fn(char num) = `  auto function_`~ num ~`()    => "Hello from function `~ num ~`!"; `; enum CardinalNumbers { n0, n1, n2, n3, n4, n5, n6, n7, n8, n9 } void main() {  assert(function_9() == "Hello from function 9!"); } ``` SDB 79
Oct 09 2023
next sibling parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Monday, 9 October 2023 at 22:49:11 UTC, Salih Dincer wrote:
 On Monday, 9 October 2023 at 16:33:32 UTC, rempas wrote:
 I'm trying to create a series of function. There will be ten 
 of them, and they will be called `function_0`, `function_1`, 
 etc. However, in my example, "stringof" returns the character 
 "i" itself and turns that into a string instead of getting its 
 actual value (number).

 Any ideas how I can achieve what I'm trying to achieve?
Great masters generally warn to stay away from stringof. Please do not use it as much as possible. The following code snippet will be useful to you: ```d alias CN = __traits(allMembers, CardinalNumbers); static foreach(i; CN) { mixin(create_fn!(i[1])); } enum create_fn(char num) = `  auto function_`~ num ~`()    => "Hello from function `~ num ~`!"; `; enum CardinalNumbers { n0, n1, n2, n3, n4, n5, n6, n7, n8, n9 } void main() {  assert(function_9() == "Hello from function 9!"); } ``` SDB 79
If count < 10 then why not just ```d import std; static foreach(c; "0123456789") {  mixin(create_fn!(c)); } enum create_fn(char num) = ` auto function_`~ num ~`() => "Hello from function `~ num ~`!"; `; void main() { assert(function_9() == "Hello from function 9!"); } ```
Oct 09 2023
parent rempas <rempas tutanota.com> writes:
On Tuesday, 10 October 2023 at 05:32:52 UTC, Imperatorn wrote:
 If count < 10 then why not just

 ```d
 import std;

     static foreach(c; "0123456789")
     {
       mixin(create_fn!(c));
     }

     enum create_fn(char num) = `
       auto function_`~ num ~`()
         => "Hello from function `~ num ~`!";
     `;

     void main()
     {
       assert(function_9() == "Hello from function 9!");
     }
 ```
Thank you! Yeah, the most clean code wins for me, so I'll use yours (if it's open source, lol)! Thank you and have an amazing day!
Oct 10 2023
prev sibling parent rempas <rempas tutanota.com> writes:
On Monday, 9 October 2023 at 22:49:11 UTC, Salih Dincer wrote:
 Great masters generally warn to stay away from stringof. Please 
 do not use it as much as possible. The following code snippet 
 will be useful to you:

 ```d
 alias CN = __traits(allMembers, CardinalNumbers);

 static foreach(i; CN)
 {
   mixin(create_fn!(i[1]));
 }

 enum create_fn(char num) = `
   auto function_`~ num ~`()
     => "Hello from function `~ num ~`!";
 `;

 enum CardinalNumbers
 {
   n0, n1, n2, n3, n4, n5, n6, n7, n8, n9
 }

 void main()
 {
   assert(function_9() == "Hello from function 9!");
 }
 ```

 SDB 79
Thank you so much! This will do the trick. Have a beautiful day!
Oct 10 2023
prev sibling parent reply Dennis <dkorpel gmail.com> writes:
On Monday, 9 October 2023 at 16:33:32 UTC, rempas wrote:
 However, in my example, "stringof" returns the character "i" 
 itself and turns that into a string instead of getting its 
 actual value (number).
The result of `.stringof` is implementation defined, it can be used for debugging but don't make your program's semantics depend on the output of it. ... ... ...That being said, this trick can be used to convert an integer to string at compile time: ```D enum itoa(int i) = i.stringof; static foreach(i; 0 .. 10) { mixin(create_fn!(itoa!i)); } ``` Technically not reliable, but I don't expect integers to ever get printed differently than a string of base 10 digits.
Oct 10 2023
next sibling parent rempas <rempas tutanota.com> writes:
On Tuesday, 10 October 2023 at 11:45:25 UTC, Dennis wrote:
 The result of `.stringof` is implementation defined, it can be 
 used for debugging but don't make your program's semantics 
 depend on the output of it.

 ...

 ...

 ...That being said, this trick can be used to convert an 
 integer to string at compile time:


 ```D
 enum itoa(int i) = i.stringof;

 static foreach(i; 0 .. 10) {
   mixin(create_fn!(itoa!i));
 }
 ```

 Technically not reliable, but I don't expect integers to ever 
 get printed differently than a string of base 10 digits.
Thank you! It is great and works great. I will however use the example from Imperatorn as it does not use ".stringof". Have an amazing day!
Oct 10 2023
prev sibling parent reply Nick Treleaven <nick geany.org> writes:
On Tuesday, 10 October 2023 at 11:45:25 UTC, Dennis wrote:
 ```D
 enum itoa(int i) = i.stringof;

 static foreach(i; 0 .. 10) {
   mixin(create_fn!(itoa!i));
 }
 ```
You can also do it using a string mixin: mixin(create_fn!(mixin("`", i, "`"))); I think that's equivalent to `i.stringof` anyway.
Oct 13 2023
parent reply rempas <rempas tutanota.com> writes:
On Friday, 13 October 2023 at 10:11:33 UTC, Nick Treleaven wrote:
 You can also do it using a string mixin:

     mixin(create_fn!(mixin("`", i, "`")));

 I think that's equivalent to `i.stringof` anyway.
Thank you for the info!
Oct 13 2023
parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Saturday, 14 October 2023 at 06:48:40 UTC, rempas wrote:
 On Friday, 13 October 2023 at 10:11:33 UTC, Nick Treleaven 
 wrote:
 You can also do it using a string mixin:

     mixin(create_fn!(mixin("`", i, "`")));

 I think that's equivalent to `i.stringof` anyway.
Thank you for the info!
You already got a lot of good answers, I thought I'd just share this for anyone searching for nogc string formatting compatible with betterC: https://code.dlang.org/packages/bc-string
Oct 15 2023
next sibling parent rempas <rempas tutanota.com> writes:
On Sunday, 15 October 2023 at 07:22:53 UTC, Imperatorn wrote:
 You already got a lot of good answers, I thought I'd just share 
 this for anyone searching for nogc string formatting compatible 
 with betterC:

 https://code.dlang.org/packages/bc-string
You thought, well, thank you very much and have a great day!
Oct 17 2023
prev sibling parent reply Salih Dincer <salihdb hotmail.com> writes:
On Sunday, 15 October 2023 at 07:22:53 UTC, Imperatorn wrote:
 You already got a lot of good answers, I thought I'd just share 
 this for anyone searching for nogc string formatting compatible 
 with betterC:

 https://code.dlang.org/packages/bc-string
Doesn't it make more sense to use [ParseResult!T parse(T)(cstring str)](https://github.com/tchaloupka/bc-string/blob/master/sour e/bc/string/conv.d) instead of nested if's here: https://github.com/tchaloupka/bc-string/blob/master/source/bc/string/numeric.d Thanks, SDB 79
Oct 17 2023
parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Tuesday, 17 October 2023 at 13:31:39 UTC, Salih Dincer wrote:
 On Sunday, 15 October 2023 at 07:22:53 UTC, Imperatorn wrote:
 You already got a lot of good answers, I thought I'd just 
 share this for anyone searching for nogc string formatting 
 compatible with betterC:

 https://code.dlang.org/packages/bc-string
Doesn't it make more sense to use [ParseResult!T parse(T)(cstring str)](https://github.com/tchaloupka/bc-string/blob/master/sour e/bc/string/conv.d) instead of nested if's here: https://github.com/tchaloupka/bc-string/blob/master/source/bc/string/numeric.d Thanks, SDB 79
Omg, yeah, that looks like some kind of hack. Make a PR :)
Oct 17 2023