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

james.p.leblanc james.p.leblanc at gmail.com
Wed Sep 1 16:02:47 UTC 2021


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



More information about the Digitalmars-d-learn mailing list