Re: Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?

2021-09-01 Thread james.p.leblanc via Digitalmars-d-learn

On Wednesday, 1 September 2021 at 22:11:29 UTC, user1234 wrote:

On Wednesday, 1 September 2021 at 22:01:12 UTC, user1234 wrote:


```

ProcessPipes gnuplot () {
__gshared ProcessPipes pipe;
return pipe.pid ? pipe : (pipe = 
pipeProcess("/usr/local/bin/gnuplot"));

}

```

user1234,

Thanks!  This is perfect, getting rid of the class altogether.

Yes, as pointed out in your response, that class was rather 
useless.
(For some unknown reason, I had been stuck on creating a 
singleton to
avoid multiple gnuplot processes -- very unnecessary as I now 
see.).


The ternary operator with the pipe id is much cleaner and leaner.

Thanks again, for your time, energy and insight.

Best Regards,
James



Re: Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?

2021-09-01 Thread user1234 via Digitalmars-d-learn

On Wednesday, 1 September 2021 at 22:01:12 UTC, user1234 wrote:
On Wednesday, 1 September 2021 at 20:59:15 UTC, james.p.leblanc 
wrote:

[...]
The question is if there is a way to enable UFCS without such 
wrapper


sorry my attention got stuck on the singleton.

So my suggestion is rather to only enable the ufcs style. This 
highlights the fact that the class is useless, you can use a 
simple getter that initializes a hidden global:


```d
module gnuplot_mod;

import std.stdio;
import std.process;
import std.algorithm : each;
import std.range : enumerate;

ProcessPipes gnuplot () {
__gshared ProcessPipes pipe;
return pipe.pid ? pipe : (pipe = 
pipeProcess("/usr/local/bin/gnuplot"));

}

static void cmd(string txt) {
with (gnuplot()) {
stdin.writeln(txt);
stdin.flush();
}
}

static void plot(double[] x, string txt = "ls 21 lw 2"){
with (gnuplot()) {
stdin.writeln("plot '-' u 1:2 with lines ", txt);
enumerate(x).each!((i,v) => stdin.writefln!"%s %f"(i, 
v))();


sorry there was a format mistake not detected at compile time.

```diff
- enumerate(x).each!((i,v) => stdin.writefln!"%s %f"(i, v))();
+ enumerate(x).each!(a => stdin.writefln!"%s %f"(a.index, 
a.value))();

```


stdin.writeln("e");
stdin.flush();
}
}

void main() {
  double[] x = [1.1, 0.2, 3.1, 2.2, 3.1, 0.6];
  double[] y = [-1.1, 0.2, -3.1, 2.2, 3.1, -0.6];
  y.plot("ls 41 lw 8");
  cmd("pause 2");
}

```





Re: Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?

2021-09-01 Thread user1234 via Digitalmars-d-learn
On Wednesday, 1 September 2021 at 20:59:15 UTC, james.p.leblanc 
wrote:

[...]
The question is if there is a way to enable UFCS without such 
wrapper


sorry my attention got stuck on the singleton.

So my suggestion is rather to only enable the ufcs style. This 
highlights the fact that the class is useless, you can use a 
simple getter that initializes a hidden global:


```d
module gnuplot_mod;

import std.stdio;
import std.process;
import std.algorithm : each;
import std.range : enumerate;

ProcessPipes gnuplot () {
__gshared ProcessPipes pipe;
return pipe.pid ? pipe : (pipe = 
pipeProcess("/usr/local/bin/gnuplot"));

}

static void cmd(string txt) {
with (gnuplot()) {
stdin.writeln(txt);
stdin.flush();
}
}

static void plot(double[] x, string txt = "ls 21 lw 2"){
with (gnuplot()) {
stdin.writeln("plot '-' u 1:2 with lines ", txt);
enumerate(x).each!((i,v) => stdin.writefln!"%s %f"(i, 
v))();

stdin.writeln("e");
stdin.flush();
}
}

void main() {
  double[] x = [1.1, 0.2, 3.1, 2.2, 3.1, 0.6];
  double[] y = [-1.1, 0.2, -3.1, 2.2, 3.1, -0.6];
  y.plot("ls 41 lw 8");
  cmd("pause 2");
}

```


Re: Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?

2021-09-01 Thread james.p.leblanc via Digitalmars-d-learn

On Wednesday, 1 September 2021 at 19:54:14 UTC, user1234 wrote:
On Wednesday, 1 September 2021 at 16:02:47 UTC, james.p.leblanc 
wrote:

Dear D-ers,

For simple plotting using a gnuplot process, I have created a 
singleton object (a stripped

down minimal working example is below.)

[...]

**However, those wrapper functions in the gnuplot_mod module 
looks a bit silly.**


[...]

Any suggestions on a better way are greatly appreciated.

Best Regards,
James


hello, I'd suggest this:

```d
shared static this() {
get(); // cache instance before main(){}
   // to get rid of the synchronized() stmt
}

static Gnuplot get() {
__gshared Gnuplot instance;
return instance ? instance : (instance = new Gnuplot());
}
```


user1234,

Thanks for your reply, I will need to look at it deeper.

I also realize that my post was not so clear, to clarify:

I needed to implement two wrapper functions ... that  are **in** 
the

module, but **outside** of the object, copied below:

**void cmd(string txt){**
**Gnuplot gp;**
**gp = gp.get();**
**gp.cmd(txt);**
**}**

**void plot(double[] x, string txt){**
**Gnuplot gp;**
**gp = gp.get();**
**gp.plot(x, txt);**
**}**

These enable use of the UFCS in main() (without prefixing with 
instantiated object's name
**gp** ).  The gp prefix only needs to be in these wrappers that 
exist in the module, not in the main().


The question is if there is a way to enable UFCS without such 
wrapper

(see example in main() in original posting).

Thanks again, and now I need to play a bit with your suggestion 
to learn

from it.

Best Regards,
James



Re: Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?

2021-09-01 Thread user1234 via Digitalmars-d-learn
On Wednesday, 1 September 2021 at 16:02:47 UTC, james.p.leblanc 
wrote:

Dear D-ers,

For simple plotting using a gnuplot process, I have created a 
singleton object (a stripped

down minimal working example is below.)

[...]

**However, those wrapper functions in the gnuplot_mod module 
looks a bit silly.**


[...]

Any suggestions on a better way are greatly appreciated.

Best Regards,
James


hello, I'd suggest this:

```d
shared static this() {
get(); // cache instance before main(){}
   // to get rid of the synchronized() stmt
}

static Gnuplot get() {
__gshared Gnuplot instance;
return instance ? instance : (instance = new Gnuplot());
}
```


Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?

2021-09-01 Thread james.p.leblanc via Digitalmars-d-learn

Dear D-ers,

For simple plotting using a gnuplot process, I have created a 
singleton object (a stripped

down minimal working example is below.)

In the example, there are two plots calls:

   1) First, call is made using the object member function 
"gp.plot(x, etc.)"
   2) The second uses a wrapper to allow use of the UFCS (uniform 
function call syntax)


The ability to use the UFCS has the usual UFCS advantages, 
additionally the coder
doesn't need to care about the actual name of the object's 
instantiation.


**However, those wrapper functions in the gnuplot_mod module 
looks a bit silly.**


**Is there a more elegant way to do this?**

First, the module:

--

   module gnuplot_mod;

   import std.stdio;
   import std.process;
   import std.conv : to;

   class Gnuplot {

  // modification of wiki.dlang.org/Low-Lock_Singleton_Pattern
  ProcessPipes pipe;
  private this() {
 this.pipe = pipeProcess("/usr/local/bin/gnuplot") ;
  }

  private static bool instantiated_;
  private __gshared Gnuplot instance_;

  static Gnuplot get() {
 if (!instantiated_) {
synchronized(Gnuplot.classinfo) {
   if (!instance_) {
  instance_ = new Gnuplot();
   }
   instantiated_ = true;
}
 }
 return instance_;
  }

  void cmd(string txt) {
 this.pipe.stdin.writeln(txt);
 this.pipe.stdin.flush();
 return;
  }

  void plot(double[] x, string txt = "ls 21 lw 2"){
 this.pipe.stdin.writeln("plot '-' u 1:2 with lines " ~ 
txt);
 foreach( ind, val ; x) this.pipe.stdin.writeln( 
to!string(ind) ~ " " ~ to!string(val) );

 this.pipe.stdin.writeln("e");
 this.pipe.stdin.flush();
  }
   }

   void cmd(string txt){
  Gnuplot gp;
  gp = gp.get();
  gp.cmd(txt);
   }

   void plot(double[] x, string txt){
  Gnuplot gp;
  gp = gp.get();
  gp.plot(x, txt);
   }

---
Now, the main ...

---

   import gnuplot_mod;
   import std.stdio;

   void main(){

  Gnuplot gp;
  gp = gp.get();

  double[] x = [1.1, 0.2, 3.1, 2.2, 3.1, 0.6];
  double[] y = [-1.1, 0.2, -3.1, 2.2, 3.1, -0.6];

  writeln("\nusing singleton's member functions: plot and 
cmd");


  gp.plot(x, "ls 31 lw 3");
  gp.cmd("pause 2");

  writeln("\nusing uniform function call syntax (UFCS): plot 
and cmd");


  y.plot("ls 41 lw 8");
  cmd("pause 2");
   }


Any suggestions on a better way are greatly appreciated.

Best Regards,
James