Jump to page: 1 2 3
Thread overview
How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?
Oct 09, 2023
rempas
Oct 09, 2023
mw
Oct 09, 2023
rempas
Oct 09, 2023
mw
Oct 09, 2023
rempas
Oct 09, 2023
Imperatorn
Oct 09, 2023
rempas
Oct 10, 2023
Hipreme
Oct 10, 2023
rempas
Oct 10, 2023
bachmeier
Oct 14, 2023
rempas
Oct 09, 2023
Jonathan M Davis
Oct 09, 2023
rempas
Oct 09, 2023
Salih Dincer
Oct 10, 2023
Imperatorn
Oct 10, 2023
rempas
Oct 10, 2023
rempas
Oct 10, 2023
Dennis
Oct 10, 2023
rempas
Oct 13, 2023
Nick Treleaven
Oct 14, 2023
rempas
Oct 15, 2023
Imperatorn
Oct 17, 2023
rempas
Oct 17, 2023
Salih Dincer
Oct 17, 2023
Imperatorn
October 09, 2023

Let's see the following example:

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?

October 09, 2023

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:

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?

October 09, 2023

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.

October 09, 2023

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.

October 09, 2023

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.

October 09, 2023

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?

October 09, 2023
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



October 09, 2023

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!

October 09, 2023
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!
October 09, 2023

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:

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

« First   ‹ Prev
1 2 3