Jump to page: 1 2 3
Thread overview
Singleton in Action?
Feb 02, 2019
Ron Tarrant
Feb 02, 2019
Russel Winder
Feb 02, 2019
Eugene Wissner
Feb 02, 2019
Neia Neutuladh
Feb 03, 2019
Ron Tarrant
Feb 03, 2019
Alex
Feb 03, 2019
Ron Tarrant
Feb 03, 2019
Russel Winder
Feb 04, 2019
Ron Tarrant
Feb 04, 2019
Kagamin
Feb 02, 2019
Ron Tarrant
Feb 02, 2019
Andre Pany
Feb 03, 2019
Ron Tarrant
Feb 03, 2019
Ron Tarrant
Feb 03, 2019
Jonathan M Davis
Feb 03, 2019
Ron Tarrant
Feb 02, 2019
angel
Feb 03, 2019
Norm
Feb 03, 2019
Norm
Feb 03, 2019
Tony
Feb 03, 2019
Jacob Carlborg
Feb 04, 2019
Ron Tarrant
Feb 04, 2019
Alex
Feb 04, 2019
Jacob Carlborg
Feb 06, 2019
Ron Tarrant
Feb 03, 2019
Dejan Lekic
Feb 04, 2019
Ron Tarrant
Feb 04, 2019
bauss
Feb 05, 2019
kdevel
February 02, 2019
Hi guys,

I ran into another snag this morning while trying to implement a singleton. I found all kinds of examples of singleton definitions, but nothing about how to put them into practice.

Can someone show me a code example for how one would actually use a singleton pattern in D? When I did the same thing in PHP, it took me forever to wrap my brain around it, so I'm hoping to get there a little faster this time.

Here's the singleton code I've been playing with:

class DSingleton
{
	private:
	// Cache instantiation flag in thread-local bool
	// Thread local
	static bool instantiated_;

	// Thread global
	__gshared DSingleton instance_;

	this()
	{
		
	} // this()

	public:
	
	static DSingleton get()
	{
		if(!instantiated_)
		{
			synchronized(DSingleton.classinfo)
			{
				if(!instance_)
				{
					instance_ = new DSingleton();
					writeln("creating");
				}

				instantiated_ = true;
			}
		}
		else
		{
			writeln("not created");
		}

		return(instance_);
		
	} // DSingleton()

} // class DSingleton

So, my big question is, do I instantiate like this:

DSingleton singleton = new DSingleton;

Or like this:

DSingleton singleton = singleton.get();

And subsequent calls would be...? The same? Using get() only?


February 02, 2019
On Sat, 2019-02-02 at 16:56 +0000, Ron Tarrant via Digitalmars-d-learn wrote:
> Hi guys,

and gals.

> I ran into another snag this morning while trying to implement a singleton. I found all kinds of examples of singleton definitions, but nothing about how to put them into practice.

General, these days, as far as I know, Singleton is considered one of the ultimate anti-patterns of software development. There are many positive reasons for this very negative view of Singleton especially if there is any hint of concurrency or parallelism involved. Also Singletons tend to deny sensible testing.

> Can someone show me a code example for how one would actually use a singleton pattern in D? When I did the same thing in PHP, it took me forever to wrap my brain around it, so I'm hoping to get there a little faster this time.

I'd suggest just not going here. Let's not have Singleton in D code.

Alternatives include "Parameterize From Above" which I believe Kevlin Henney pushes strongly, and indeed he may be the source of the "pattern". (I believe it is a design not a pattern using the proper definition of pattern.)

If the resource really is "singleton" then creating an actor or agent is now the usual solution in languages such as D, Rust, Go, even C++.

> 
[…]
> So, my big question is, do I instantiate like this:
> 
> DSingleton singleton = new DSingleton;

This seems wrong.

> Or like this:
> 
> DSingleton singleton = singleton.get();

getting seems like the one true way, if you really have to do this.

Can I indent that Singleton not be part of the canon of D programming.

> And subsequent calls would be...? The same? Using get() only?
> 
> 
-- 
Russel.
===========================================
Dr Russel Winder      t: +44 20 7585 2200
41 Buckmaster Road    m: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



February 02, 2019
On Saturday, 2 February 2019 at 16:56:45 UTC, Ron Tarrant wrote:
> Hi guys,
>
> I ran into another snag this morning while trying to implement a singleton. I found all kinds of examples of singleton definitions, but nothing about how to put them into practice.
>
> Can someone show me a code example for how one would actually use a singleton pattern in D? When I did the same thing in PHP, it took me forever to wrap my brain around it, so I'm hoping to get there a little faster this time.
>
> Here's the singleton code I've been playing with:
>
> class DSingleton
> {
> 	private:
> 	// Cache instantiation flag in thread-local bool
> 	// Thread local
> 	static bool instantiated_;
>
> 	// Thread global
> 	__gshared DSingleton instance_;
>
> 	this()
> 	{
> 		
> 	} // this()
>
> 	public:
> 	
> 	static DSingleton get()
> 	{
> 		if(!instantiated_)
> 		{
> 			synchronized(DSingleton.classinfo)
> 			{
> 				if(!instance_)
> 				{
> 					instance_ = new DSingleton();
> 					writeln("creating");
> 				}
>
> 				instantiated_ = true;
> 			}
> 		}
> 		else
> 		{
> 			writeln("not created");
> 		}
>
> 		return(instance_);
> 		
> 	} // DSingleton()
>
> } // class DSingleton
>
> So, my big question is, do I instantiate like this:
>
> DSingleton singleton = new DSingleton;
>
> Or like this:
>
> DSingleton singleton = singleton.get();
>
> And subsequent calls would be...? The same? Using get() only?

Imho it looks fine.

For creation get() should be always used, since it is the most convenient way to ensure that there is really only one instance of the singleton. Just make this() private, so only you can create new instances:

private this()
{
}

And you probably don't need instantiated_, you can always check whether instance_ is null or not. So:

if (instance_ is null)
{
    ...
}
else
{
   ...
}
February 02, 2019
Thanks for the replies, fellow programmers. (generic, unisex, PC, and all-encompassing)

If I could trouble someone for a complete working example so I have something to study, that would be excellent.
February 02, 2019
On Saturday, 2 February 2019 at 19:23:58 UTC, Ron Tarrant wrote:
> Thanks for the replies, fellow programmers. (generic, unisex, PC, and all-encompassing)
>
> If I could trouble someone for a complete working example so I have something to study, that would be excellent.

I found here an example:
https://rosettacode.org/wiki/Singleton#D

Kind regards
Andre

February 02, 2019
On Sat, 02 Feb 2019 17:34:11 +0000, Eugene Wissner wrote:
> For creation get() should be always used, since it is the most convenient way to ensure that there is really only one instance of the singleton. Just make this() private, so only you can create new instances:
> 
> private this()
> {
> }

And consider putting the class in its own source file.
February 02, 2019
On Saturday, 2 February 2019 at 19:23:58 UTC, Ron Tarrant wrote:
> Thanks for the replies, fellow programmers. (generic, unisex, PC, and all-encompassing)
>
> If I could trouble someone for a complete working example so I have something to study, that would be excellent.


I think that's what you really need:
[1] https://davesdprogramming.wordpress.com/
[2] https://www.youtube.com/watch?v=ZHmIAdlNtiM

February 03, 2019
On Saturday, 2 February 2019 at 16:56:45 UTC, Ron Tarrant wrote:
> Hi guys,
>
> I ran into another snag this morning while trying to implement a singleton. I found all kinds of examples of singleton definitions, but nothing about how to put them into practice.
>
> [...]

If you haven't already been to the d-idioms site it is well worth a look:

https://p0nce.github.io/d-idioms/

It has a singleton example that you may find useful.

https://p0nce.github.io/d-idioms/#Leveraging-TLS-for-a-fast-thread-safe-singleton

bye,
norm
February 03, 2019
On Saturday, 2 February 2019 at 16:56:45 UTC, Ron Tarrant wrote:
> Hi guys,
>
> I ran into another snag this morning while trying to implement a singleton. I found all kinds of examples of singleton definitions, but nothing about how to put them into practice.
>
> Can someone show me a code example for how one would actually use a singleton pattern in D? When I did the same thing in PHP, it took me forever to wrap my brain around it, so I'm hoping to get there a little faster this time.
>
> Here's the singleton code I've been playing with:
>
> class DSingleton
> {
> 	private:
> 	// Cache instantiation flag in thread-local bool
> 	// Thread local
> 	static bool instantiated_;
>
> 	// Thread global
> 	__gshared DSingleton instance_;
>
> 	this()
> 	{
> 		
> 	} // this()
>
> 	public:
> 	
> 	static DSingleton get()
> 	{
> 		if(!instantiated_)
> 		{
> 			synchronized(DSingleton.classinfo)
> 			{
> 				if(!instance_)
> 				{
> 					instance_ = new DSingleton();
> 					writeln("creating");
> 				}
>
> 				instantiated_ = true;
> 			}
> 		}
> 		else
> 		{
> 			writeln("not created");
> 		}
>
> 		return(instance_);
> 		
> 	} // DSingleton()
>
> } // class DSingleton
>
> So, my big question is, do I instantiate like this:
>
> DSingleton singleton = new DSingleton;
>
> Or like this:
>
> DSingleton singleton = singleton.get();
>
> And subsequent calls would be...? The same? Using get() only?

Sorry, I should read the post fully before replying, my bad. You access the singleton via the get() function whenever you need it. It is static so there's no need to create a copy of the instance in a "singleton" variable.

DSingleton singleton = new DSingleton; is bad. It bypasses all the checks in the "get()" method to ensure it is a singleton and outside the module where you defined DSingleton it won't compile.

bye,
norm









February 03, 2019
On Saturday, 2 February 2019 at 16:56:45 UTC, Ron Tarrant wrote:
>
> So, my big question is, do I instantiate like this:
>
> DSingleton singleton = new DSingleton;
>
> Or like this:
>
> DSingleton singleton = singleton.get();
>
> And subsequent calls would be...? The same? Using get() only?

This seems to be a case where D's definition of "private" can cause confusion versus examples from other languages with private as "access only inside the class". In other languages

DSingleton singleton = new DSingleton;

would never compile (the desired behavior), since the constructor is private.

But D allows it in some cases due to "private to class OR module". If DSingleton is in the same module, as for example in a small test program with DSingleton and main() in the same file, then it compiles.

So I think your code is fine, it's just that it can be circumvented - the private constructor can be called - if DSingledton and the instantiating code are in the same module.




« First   ‹ Prev
1 2 3