Thread overview
scope struct?
Oct 17, 2011
Steve Teale
Oct 17, 2011
deadalnix
Oct 23, 2011
Christophe
October 17, 2011
Is not needed because structs are inherently scope.

I'm sure experienced D programmers do this all the time when they want something done on exit from a scope, but I never had, and maybe there are others who haven't, particularly if coming from a C++ 'use classes for everything' background.

import std.stdio;

bool glob;

struct Sentinel
{
   void function() doit;
   bool already;
   this(void function() f)
   {
      doit = f;
      already = false;
   }

   ~this()
   {
      if (!already)
      {
         writeln("Doing it now");
         doit();
      }
      else
         writeln("Won't bother");
   }

   void dontBother() { already = true; }
}

void reset() { glob = false; }

void main(string[] args)
{
   glob = true;
   {
      Sentinel s = Sentinel(&reset);
      writeln("Doing stuff in the scope");
      if (args.length >= 2 && args[1] == "db")
         s.dontBother();
   }
   writeln(glob);
}
October 17, 2011
Nice trick ! However, in D, you have scope(exit) scope(success) and scope(failure) to do similar stuffs.

I personally use both, on a case by case basis.

Le 17/10/2011 06:47, Steve Teale a écrit :
> Is not needed because structs are inherently scope.
>
> I'm sure experienced D programmers do this all the time when they want
> something done on exit from a scope, but I never had, and maybe there are
> others who haven't, particularly if coming from a C++ 'use classes for
> everything' background.
>
> import std.stdio;
>
> bool glob;
>
> struct Sentinel
> {
>     void function() doit;
>     bool already;
>     this(void function() f)
>     {
>        doit = f;
>        already = false;
>     }
>
>     ~this()
>     {
>        if (!already)
>        {
>           writeln("Doing it now");
>           doit();
>        }
>        else
>           writeln("Won't bother");
>     }
>
>     void dontBother() { already = true; }
> }
>
> void reset() { glob = false; }
>
> void main(string[] args)
> {
>     glob = true;
>     {
>        Sentinel s = Sentinel(&reset);
>        writeln("Doing stuff in the scope");
>        if (args.length>= 2&&  args[1] == "db")
>           s.dontBother();
>     }
>     writeln(glob);
> }

October 23, 2011
Steve Teale , dans le message (digitalmars.D.learn:30117), a écrit :
> Is not needed because structs are inherently scope.
> 
> I'm sure experienced D programmers do this all the time when they want something done on exit from a scope, but I never had, and maybe there are others who haven't, particularly if coming from a C++ 'use classes for everything' background.
> 
> import std.stdio;
> 
> bool glob;
> 
> struct Sentinel
> {
>    void function() doit;
>    bool already;
>    this(void function() f)
>    {
>       doit = f;
>       already = false;
>    }
> 
>    ~this()
>    {
>       if (!already)
>       {
>          writeln("Doing it now");
>          doit();
>       }
>       else
>          writeln("Won't bother");
>    }
> 
>    void dontBother() { already = true; }
> }
> 
> void reset() { glob = false; }
> 
> void main(string[] args)
> {
>    glob = true;
>    {
>       Sentinel s = Sentinel(&reset);
>       writeln("Doing stuff in the scope");
>       if (args.length >= 2 && args[1] == "db")
>          s.dontBother();
>    }
>    writeln(glob);
> }



void main(string[] args)
{
  glob = true;
  {
    dontBother=false;
    scope(exit)
    {
      if (!dontBother)
        {
          writeln("Doing it now");
          glob = false;
        }
      else
	{
          writeln("Don't bother");
        }
     }

     writeln("Doing stuff in the scope");
     if (args.length >= 2 && args[1] == "db")
       dontBother() = true;
  }
  writeln(glob);
}


If you're not running a test with a lot of writing, the scope clause is just:

scope(exit) if (!dontBother) glob() = false;

The scope exit clause will be run even if you exit via an exception (just like the sentinel's dstructor).

As you can see, D as its own syntax to make things when the scope exits, so you don't need to build a sentinel struct. http://d-programming-language.org/exception-safe.html