Singleton: Difference between revisions
m (→{{header|Kotlin}}: Adjusted line spacing) |
(Add Ecstasy example) |
||
(31 intermediate revisions by 21 users not shown) | |||
Line 6: | Line 6: | ||
=={{header|ActionScript}}== |
=={{header|ActionScript}}== |
||
< |
<syntaxhighlight lang="actionscript">package |
||
{ |
{ |
||
public class Singleton |
public class Singleton |
||
Line 25: | Line 25: | ||
} |
} |
||
internal class SingletonEnforcer {}</ |
internal class SingletonEnforcer {}</syntaxhighlight> |
||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
===Non Thread Safe=== |
===Non Thread Safe=== |
||
< |
<syntaxhighlight lang="ada">package Global_Singleton is |
||
procedure Set_Data (Value : Integer); |
procedure Set_Data (Value : Integer); |
||
function Get_Data return Integer; |
function Get_Data return Integer; |
||
Line 38: | Line 38: | ||
end record; |
end record; |
||
Instance : Instance_Type; |
Instance : Instance_Type; |
||
end Global_Singleton;</ |
end Global_Singleton;</syntaxhighlight> |
||
< |
<syntaxhighlight lang="ada">package body Global_Singleton is |
||
-------------- |
-------------- |
||
Line 60: | Line 60: | ||
end Get_Data; |
end Get_Data; |
||
end Global_Singleton;</ |
end Global_Singleton;</syntaxhighlight> |
||
===Thread Safe=== |
===Thread Safe=== |
||
< |
<syntaxhighlight lang="ada">package Protected_Singleton is |
||
procedure Set_Data (Value : Integer); |
procedure Set_Data (Value : Integer); |
||
function Get_Data return Integer; |
function Get_Data return Integer; |
||
Line 73: | Line 73: | ||
Data : Integer := 0; |
Data : Integer := 0; |
||
end Instance_Type; |
end Instance_Type; |
||
end Protected_Singleton;</ |
end Protected_Singleton;</syntaxhighlight> |
||
< |
<syntaxhighlight lang="ada">package body Protected_Singleton is |
||
-------------- |
-------------- |
||
Line 121: | Line 121: | ||
end Instance; |
end Instance; |
||
end Protected_Singleton;</ |
end Protected_Singleton;</syntaxhighlight> |
||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
{{works with | AutoHotkey_L}} |
{{works with | AutoHotkey_L}} |
||
Translation of python borg pattern |
Translation of python borg pattern |
||
< |
<syntaxhighlight lang="autohotkey">b1 := borg() |
||
b2 := borg() |
b2 := borg() |
||
msgbox % "b1 is b2? " . (b1 == b2) |
msgbox % "b1 is b2? " . (b1 == b2) |
||
Line 153: | Line 153: | ||
brg[1, name] := val |
brg[1, name] := val |
||
Return val |
Return val |
||
}</ |
}</syntaxhighlight> |
||
=={{header|BASIC}}== |
|||
==={{header|FreeBASIC}}=== |
|||
<syntaxhighlight lang="freebasic"> |
|||
REM Sacado del forum de FreeBASIC (https://www.freebasic.net/forum/viewtopic.php?t=20432) |
|||
Type singleton |
|||
Public : |
|||
Declare Static Function crearInstancia() As singleton Ptr |
|||
Declare Destructor () |
|||
Dim i As Integer |
|||
Private : |
|||
Declare Constructor() |
|||
Declare Constructor(Byref rhs As singleton) |
|||
Declare Static Function instancia(Byval crear As Integer) As singleton Ptr |
|||
End Type |
|||
Static Function singleton.crearInstancia() As singleton Ptr |
|||
Return singleton.instancia(1) |
|||
End Function |
|||
Static Function singleton.instancia(Byval crear As Integer) As singleton Ptr |
|||
Static ref As singleton Ptr = 0 |
|||
Function = 0 |
|||
If crear = 0 Then |
|||
ref = 0 |
|||
Elseif ref = 0 Then |
|||
ref = New singleton |
|||
Function = ref |
|||
End If |
|||
End Function |
|||
Constructor singleton () |
|||
End Constructor |
|||
Destructor singleton() |
|||
singleton.instancia(0) |
|||
End Destructor |
|||
'----------------------------------------------------------------------------- |
|||
Dim As singleton Ptr ps1 = singleton.crearinstancia() |
|||
ps1->i = 1234 |
|||
Print ps1, ps1->i |
|||
Dim As singleton Ptr ps2 = singleton.crearinstancia() |
|||
Print ps2 |
|||
Delete ps1 |
|||
Dim As singleton Ptr ps3 = singleton.crearinstancia() |
|||
Print ps3, ps3->i |
|||
Delete ps3 |
|||
Sleep |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
2038352 1234 |
|||
0 |
|||
2038352 0 |
|||
</pre> |
|||
==={{header|OxygenBasic}}=== |
|||
<syntaxhighlight lang="oxygenbasic"> |
|||
Class Singleton |
|||
static sys inst 'private |
|||
int instantiated() { return inst } |
|||
void constructor(){ if not inst then inst=@this } |
|||
'all other methods start with @this=inst |
|||
end class |
|||
'if not singleton.instantiated |
|||
new Singleton MySingleton |
|||
'endif |
|||
</syntaxhighlight> |
|||
==={{header|PureBasic}}=== |
|||
====Native version==== |
|||
Thread safe version. |
|||
<syntaxhighlight lang="purebasic">Global SingletonSemaphore=CreateSemaphore(1) |
|||
Interface OO_Interface ; Interface for any value of this type |
|||
Get.i() |
|||
Set(Value.i) |
|||
Destroy() |
|||
EndInterface |
|||
Structure OO_Structure ; The *VTable structure |
|||
Get.i |
|||
Set.i |
|||
Destroy.i |
|||
EndStructure |
|||
Structure OO_Var |
|||
*VirtualTable.OO_Structure |
|||
Value.i |
|||
EndStructure |
|||
Procedure OO_Get(*Self.OO_Var) |
|||
ProcedureReturn *Self\Value |
|||
EndProcedure |
|||
Procedure OO_Set(*Self.OO_Var, n) |
|||
*Self\Value = n |
|||
EndProcedure |
|||
Procedure CreateSingleton() |
|||
If TrySemaphore(SingletonSemaphore) |
|||
*p.OO_Var = AllocateMemory(SizeOf(OO_Var)) |
|||
If *p |
|||
*p\VirtualTable = ?VTable |
|||
EndIf |
|||
EndIf |
|||
ProcedureReturn *p |
|||
EndProcedure |
|||
Procedure OO_Destroy(*Self.OO_Var) |
|||
FreeMemory(*Self) |
|||
SignalSemaphore(SingletonSemaphore) |
|||
EndProcedure |
|||
DataSection |
|||
VTable: |
|||
Data.i @OO_Get() |
|||
Data.i @OO_Set() |
|||
Data.i @OO_Destroy() |
|||
EndDataSection</syntaxhighlight> |
|||
====Simple OOP extension==== |
|||
Using the open-source precompiler [http://www.development-lounge.de/viewtopic.php?t=5915 SimpleOOP]. |
|||
<syntaxhighlight lang="purebasic">Singleton Class Demo |
|||
BeginPrivate |
|||
Name$ |
|||
X.i |
|||
EndPrivate |
|||
Public Method Init(Name$) |
|||
This\Name$ = Name$ |
|||
EndMethod |
|||
Public Method GetX() |
|||
MethodReturn This\X |
|||
EndMethod |
|||
Public Method SetX(n) |
|||
This\X = n |
|||
EndMethod |
|||
Public Method Hello() |
|||
MessageRequester("Hello!", "I'm "+This\Name$) |
|||
EndMethod |
|||
EndClass</syntaxhighlight> |
|||
=={{header|C}}== |
=={{header|C}}== |
||
Since C doesn't really support classes anyhow, there's not much to do. If you want somethin akin to a singleton, what you do is first declare the interface functions in a header (.h) file. |
Since C doesn't really support classes anyhow, there's not much to do. If you want somethin akin to a singleton, what you do is first declare the interface functions in a header (.h) file. |
||
< |
<syntaxhighlight lang="c">#ifndef SILLY_H |
||
#define SILLY_H |
#define SILLY_H |
||
Line 163: | Line 315: | ||
extern int PlayFetchWithDog( float weightOfStick); |
extern int PlayFetchWithDog( float weightOfStick); |
||
#endif</ |
#endif</syntaxhighlight> |
||
Then in a separate C source (.c) file, define your structures, variables and functions. |
Then in a separate C source (.c) file, define your structures, variables and functions. |
||
< |
<syntaxhighlight lang="c">... |
||
#include "silly.h" |
#include "silly.h" |
||
Line 189: | Line 341: | ||
{ ... |
{ ... |
||
if(weightOfStick < lazyDog.max_stick_weight){... |
if(weightOfStick < lazyDog.max_stick_weight){... |
||
}</ |
}</syntaxhighlight> |
||
Code using the singleton includes the header and cannot create a |
Code using the singleton includes the header and cannot create a |
||
struct sDog as the definition is only in the C source (or other header privately included by the silly.c source). Only the functions declared in the header may be used externally. |
struct sDog as the definition is only in the C source (or other header privately included by the silly.c source). Only the functions declared in the header may be used externally. |
||
< |
<syntaxhighlight lang="c">... |
||
#include "silly.h" |
#include "silly.h" |
||
... |
... |
||
Line 198: | Line 350: | ||
JumpOverTheDog( 4); |
JumpOverTheDog( 4); |
||
retrieved = PlayFetchWithDog( 3.1); |
retrieved = PlayFetchWithDog( 3.1); |
||
...</ |
...</syntaxhighlight> |
||
=={{header|C++}}== |
|||
===Thread-safe=== |
|||
'''Operating System:''' Microsoft Windows NT/XP/Vista |
|||
:Uses a [[Win32]] flavor [[Mutex#Win32|Mutex]] - a [[POSIX]] flavor [[Mutex#POSIX|Mutex]] could be used. |
|||
<lang cpp>class Singleton |
|||
{ |
|||
public: |
|||
static Singleton* Instance() |
|||
{ |
|||
// We need to ensure that we don't accidentally create two Singletons |
|||
HANDLE hMutex = CreateMutex(NULL, FALSE, "MySingletonMutex"); |
|||
WaitForSingleObject(hMutex, INFINITE); |
|||
// Create the instance of the class. |
|||
// Since it's a static variable, if the class has already been created, |
|||
// It won't be created again. |
|||
static Singleton myInstance; |
|||
// Release our mutex so that other application threads can use this function |
|||
ReleaseMutex( hMutex ); |
|||
// Free the handle |
|||
CloseHandle( hMutex ); |
|||
// Return a pointer to our mutex instance. |
|||
return &myInstance; |
|||
} |
|||
// Any other public methods |
|||
protected: |
|||
Singleton() |
|||
{ |
|||
// Constructor code goes here. |
|||
} |
|||
~Singleton() |
|||
{ |
|||
// Destructor code goes here. |
|||
} |
|||
// And any other protected methods. |
|||
}</lang> |
|||
===Non-Thread-Safe=== |
|||
This version doesn't require [[Mutex#C|Mutex]], but it is not safe in a multi-threaded environment (before C++11). |
|||
<lang cpp>class Singleton |
|||
{ |
|||
public: |
|||
static Singleton* Instance() |
|||
{ |
|||
// Since it's a static variable, if the class has already been created, |
|||
// It won't be created again. |
|||
static Singleton myInstance; |
|||
// Return a pointer to our mutex instance. |
|||
return &myInstance; |
|||
} |
|||
// Any other public methods |
|||
protected: |
|||
Singleton() |
|||
{ |
|||
// Constructor code goes here. |
|||
} |
|||
~Singleton() |
|||
{ |
|||
// Destructor code goes here. |
|||
} |
|||
// And any other protected methods. |
|||
}</lang> |
|||
=== Thread safe (since C++11) === |
|||
This will be thread safe since C++11, where static variables is always thread-safe (according to section 6.7 of The Standard). |
|||
<lang cpp>class Singleton |
|||
{ |
|||
public: |
|||
static Singleton & Instance() |
|||
{ |
|||
// Since it's a static variable, if the class has already been created, |
|||
// It won't be created again. |
|||
// And it **is** thread-safe in C++11. |
|||
static Singleton myInstance; |
|||
// Return a reference to our instance. |
|||
return myInstance; |
|||
} |
|||
// delete copy and move constructors and assign operators |
|||
Singleton(Singleton const&) = delete; // Copy construct |
|||
Singleton(Singleton&&) = delete; // Move construct |
|||
Singleton& operator=(Singleton const&) = delete; // Copy assign |
|||
Singleton& operator=(Singleton &&) = delete; // Move assign |
|||
// Any other public methods |
|||
protected: |
|||
Singleton() |
|||
{ |
|||
// Constructor code goes here. |
|||
} |
|||
~Singleton() |
|||
{ |
|||
// Destructor code goes here. |
|||
} |
|||
// And any other protected methods. |
|||
}</lang> |
|||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
Line 317: | Line 356: | ||
Performance suffers because the lock is acquired every time Instance is accessed.<br /> |
Performance suffers because the lock is acquired every time Instance is accessed.<br /> |
||
This implementation is extremely slow and should not be used (but is seen often). |
This implementation is extremely slow and should not be used (but is seen often). |
||
< |
<syntaxhighlight lang="csharp">public sealed class Singleton1 //Lazy: Yes ||| Thread-safe: Yes ||| Uses locking: Yes |
||
{ |
{ |
||
private static Singleton1 instance; |
private static Singleton1 instance; |
||
Line 332: | Line 371: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
===Fixes excessive locking by double-checking for null.=== |
===Fixes excessive locking by double-checking for null.=== |
||
Still uses locking and implementation is ugly and verbose. |
Still uses locking and implementation is ugly and verbose. |
||
< |
<syntaxhighlight lang="csharp">public sealed class Singleton2 //Lazy: Yes ||| Thread-safe: Yes ||| Uses locking: Yes, but only once |
||
{ |
{ |
||
private static Singleton2 instance; |
private static Singleton2 instance; |
||
Line 353: | Line 392: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
===Really simple implementation without locking.=== |
===Really simple implementation without locking.=== |
||
It still is not completely lazy. If there are other static members, accessing any of those will still cause initialization. |
It still is not completely lazy. If there are other static members, accessing any of those will still cause initialization. |
||
< |
<syntaxhighlight lang="csharp">public sealed class Singleton3 //Lazy: Yes, but not completely ||| Thread-safe: Yes ||| Uses locking: No |
||
{ |
{ |
||
private static Singleton3 Instance { get; } = new Singleton3(); |
private static Singleton3 Instance { get; } = new Singleton3(); |
||
static Singleton3() { } |
static Singleton3() { } |
||
}</ |
}</syntaxhighlight> |
||
===Truly lazy by using an inner class.=== |
===Truly lazy by using an inner class.=== |
||
This version is completely lazy but the code looks more complicated than it needs to be. |
This version is completely lazy but the code looks more complicated than it needs to be. |
||
< |
<syntaxhighlight lang="csharp">public sealed class Singleton4 //Lazy: Yes ||| Thread-safe: Yes ||| Uses locking: No |
||
{ |
{ |
||
public static Singleton4 Instance => SingletonHolder.instance; |
public static Singleton4 Instance => SingletonHolder.instance; |
||
Line 376: | Line 415: | ||
internal static readonly Singleton4 instance = new Singleton4(); |
internal static readonly Singleton4 instance = new Singleton4(); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
===Using Lazy<T>=== |
===Using Lazy<T>=== |
||
C# has a dedicated type for lazy initialization: Lazy<T>.<br /> |
C# has a dedicated type for lazy initialization: Lazy<T>.<br /> |
||
It makes implementing a Singleton really easy. Recommended. |
It makes implementing a Singleton really easy. Recommended. |
||
< |
<syntaxhighlight lang="csharp">public sealed class Singleton5 //Lazy: Yes ||| Thread-safe: Yes ||| Uses locking: No |
||
{ |
{ |
||
private static readonly Lazy<Singleton5> lazy = new Lazy<Singleton5>(() => new Singleton5()); |
private static readonly Lazy<Singleton5> lazy = new Lazy<Singleton5>(() => new Singleton5()); |
||
public static Singleton5 Instance => lazy.Value; |
public static Singleton5 Instance => lazy.Value; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
|||
A generic singleton template class (implemented via the "Curiously Recurring Template Pattern"[https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern]). Warning: if using a version of C++ prior to C++11, a [[Mutex#C|mutex]] (or similar) is required to access static variables within a multi-threaded program. |
|||
<syntaxhighlight lang="cpp"> |
|||
#include <stdexcept> |
|||
template <typename Self> |
|||
class singleton |
|||
{ |
|||
protected: |
|||
static Self* |
|||
sentry; |
|||
public: |
|||
static Self& |
|||
instance() |
|||
{ |
|||
return *sentry; |
|||
} |
|||
singleton() |
|||
{ |
|||
if(sentry) |
|||
throw std::logic_error("Error: attempt to instantiate a singleton over a pre-existing one!"); |
|||
sentry = (Self*)this; |
|||
} |
|||
virtual ~singleton() |
|||
{ |
|||
if(sentry == this) |
|||
sentry = 0; |
|||
} |
|||
}; |
|||
template <typename Self> |
|||
Self* |
|||
singleton<Self>::sentry = 0; |
|||
/* |
|||
Example usage: |
|||
*/ |
|||
#include <iostream> |
|||
#include <string> |
|||
using namespace |
|||
std; |
|||
class controller : public singleton<controller> |
|||
{ |
|||
public: |
|||
controller(string const& name) |
|||
: name(name) |
|||
{ |
|||
trace("begin"); |
|||
} |
|||
~controller() |
|||
{ |
|||
trace("end"); |
|||
} |
|||
void |
|||
work() |
|||
{ |
|||
trace("doing stuff"); |
|||
} |
|||
void |
|||
trace(string const& message) |
|||
{ |
|||
cout << name << ": " << message << endl; |
|||
} |
|||
string |
|||
name; |
|||
}; |
|||
int |
|||
main() |
|||
{ |
|||
controller* |
|||
first = new controller("first"); |
|||
controller::instance().work(); |
|||
delete first; |
|||
/* |
|||
No problem, our first controller no longer exists... |
|||
*/ |
|||
controller |
|||
second("second"); |
|||
controller::instance().work(); |
|||
try |
|||
{ |
|||
/* |
|||
Never happens... |
|||
*/ |
|||
controller |
|||
goner("goner"); |
|||
controller::instance().work(); |
|||
} |
|||
catch(exception const& error) |
|||
{ |
|||
cout << error.what() << endl; |
|||
} |
|||
controller::instance().work(); |
|||
/* |
|||
Never happens (and depending on your system this may or may not print a helpful message!) |
|||
*/ |
|||
controller |
|||
goner("goner"); |
|||
controller::instance().work(); |
|||
} |
|||
</syntaxhighlight> |
|||
=={{header|Caché ObjectScript}}== |
=={{header|Caché ObjectScript}}== |
||
Line 392: | Line 536: | ||
In Caché, each job runs in a self-contained execution environment (i.e. a separate process instead of a thread). However, it is possible for each process to share data through multidimensional storage (global variables). This is because when the Caché virtual machine starts, it allocates a single, large chunk of shared memory to allow all Caché processes to access this data simultaneously. However, it is the responsibility of the application developer to ensure read and write access to objects is properly co-ordinated (or 'synchronized') between processes to prevent concurrency problems. Also, Caché defines any global variable whose name starts with 'CacheTemp' as being temporary, which means changes are not usually written to disk and are instead maintained within the in-memory buffer pool. |
In Caché, each job runs in a self-contained execution environment (i.e. a separate process instead of a thread). However, it is possible for each process to share data through multidimensional storage (global variables). This is because when the Caché virtual machine starts, it allocates a single, large chunk of shared memory to allow all Caché processes to access this data simultaneously. However, it is the responsibility of the application developer to ensure read and write access to objects is properly co-ordinated (or 'synchronized') between processes to prevent concurrency problems. Also, Caché defines any global variable whose name starts with 'CacheTemp' as being temporary, which means changes are not usually written to disk and are instead maintained within the in-memory buffer pool. |
||
< |
<syntaxhighlight lang="cos"> |
||
/// The <CLASS>Singleton</CLASS> class represents a global singleton object that can |
/// The <CLASS>Singleton</CLASS> class represents a global singleton object that can |
||
/// be instantiated by multiple processes. The 'Get' class method is used to obtain |
/// be instantiated by multiple processes. The 'Get' class method is used to obtain |
||
Line 524: | Line 668: | ||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out|Examples}} |
{{out|Examples}} |
||
Line 538: | Line 682: | ||
For a simple example, the following program constructs English sentences without worrying about extra space occurring at points where no text (<code>the-empty-phrase</code>, our singleton) is inserted. |
For a simple example, the following program constructs English sentences without worrying about extra space occurring at points where no text (<code>the-empty-phrase</code>, our singleton) is inserted. |
||
< |
<syntaxhighlight lang="lisp">(defgeneric concat (a b) |
||
(:documentation "Concatenate two phrases.")) |
(:documentation "Concatenate two phrases.")) |
||
Line 561: | Line 705: | ||
(dolist (q (list 'the-empty-phrase |
(dolist (q (list 'the-empty-phrase |
||
(make-instance 'nonempty-phrase :text "up the hill"))) |
(make-instance 'nonempty-phrase :text "up the hill"))) |
||
(write-line (text (reduce #'concat (list before p mid q after))))))))</ |
(write-line (text (reduce #'concat (list before p mid q after))))))))</syntaxhighlight> |
||
Thread safety is irrelevant since the singleton is created at load time, not first access. |
Thread safety is irrelevant since the singleton is created at load time, not first access. |
||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang="d">module singleton ; |
||
import std.stdio ; |
import std.stdio ; |
||
import std.thread ; |
import std.thread ; |
||
Line 625: | Line 769: | ||
x.wait ; y.wait ; z.wait ; |
x.wait ; y.wait ; z.wait ; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>>>Mary come in. |
<pre>>>Mary come in. |
||
Line 649: | Line 793: | ||
=={{header|Delphi}} and {{header|Pascal}}== |
=={{header|Delphi}} and {{header|Pascal}}== |
||
Detailed explanation [http://www.yanniel.info/2010/10/singleton-pattern-delphi.html here]. (Delphi started out as an object-oriented version of Pascal.) |
Detailed explanation [http://www.yanniel.info/2010/10/singleton-pattern-delphi.html here]. (Delphi started out as an object-oriented version of Pascal.) |
||
< |
<syntaxhighlight lang="delphi">unit Singleton; |
||
interface |
interface |
||
Line 688: | Line 832: | ||
end; |
end; |
||
end.</ |
end.</syntaxhighlight> |
||
=={{header|E}}== |
=={{header|E}}== |
||
Since E uses closure-style objects rather than classes, a singleton is simply an object which is defined at the top level of the program, not inside any method. There are no thread-safety issues since the singleton, like every other object, belongs to some particular [http://www.erights.org/elib/concurrency/vat.html vat] (but can be remotely invoked from other vats). |
Since E uses closure-style objects rather than classes, a singleton is simply an object which is defined at the top level of the program, not inside any method. There are no thread-safety issues since the singleton, like every other object, belongs to some particular [http://www.erights.org/elib/concurrency/vat.html vat] (but can be remotely invoked from other vats). |
||
< |
<syntaxhighlight lang="e">def aSingleton { |
||
# ... |
# ... |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Ecstasy}}== |
|||
The <code>static</code> keyword in a class declaration will compile that class as a singleton. It is legal to define <code>const</code> (i.e. immutable) and <code>service</code> classes as singletons. Modules, packages, and enumeration values are always singleton classes. It is <b>not</b> legal to define normal <code>class</code> classes as singletons, because normal classes are mutable, and Ecstasy does not allow shared mutable state. |
|||
The name of the class is used to specify that singleton instance: |
|||
<syntaxhighlight lang="ecstasy"> |
|||
module test { |
|||
static service Singleton { |
|||
private Int counter; |
|||
String fooHasBeenCalled() { |
|||
return $"{++counter} times"; |
|||
} |
|||
} |
|||
void run() { |
|||
@Inject Console console; |
|||
for (Int i : 1..5) { |
|||
console.print($"{Singleton.fooHasBeenCalled()=}"); |
|||
} |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
x$ xec test |
|||
Singleton.fooHasBeenCalled()=1 times |
|||
Singleton.fooHasBeenCalled()=2 times |
|||
Singleton.fooHasBeenCalled()=3 times |
|||
Singleton.fooHasBeenCalled()=4 times |
|||
Singleton.fooHasBeenCalled()=5 times |
|||
</pre> |
|||
=={{header|Eiffel}}== |
=={{header|Eiffel}}== |
||
Line 701: | Line 878: | ||
'''Implementation:''' |
'''Implementation:''' |
||
< |
<syntaxhighlight lang="eiffel">class |
||
SINGLETON |
SINGLETON |
||
create {SINGLETON_ACCESS} |
create {SINGLETON_ACCESS} |
||
Line 707: | Line 884: | ||
feature |
feature |
||
-- singleton features go here |
-- singleton features go here |
||
end</ |
end</syntaxhighlight> |
||
< |
<syntaxhighlight lang="eiffel">frozen class |
||
SINGLETON_ACCESS |
SINGLETON_ACCESS |
||
feature |
feature |
||
Line 717: | Line 894: | ||
Result /= Void |
Result /= Void |
||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
'''Usage:''' |
'''Usage:''' |
||
< |
<syntaxhighlight lang="eiffel">s: SINGLETON -- declaration somewhere |
||
s := (create{SINGLETON_ACCESS}).singleton -- in some routine</syntaxhighlight> |
|||
s := (create{SINGLETON_ACCESS}).singleton -- in some routine</lang> |
|||
=={{header|Elena}}== |
=={{header|Elena}}== |
||
Stateless singleton |
Stateless singleton |
||
< |
<syntaxhighlight lang="elena"> |
||
singleton Singleton |
|||
{ |
{ |
||
// ... |
// ... |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Normal singleton |
Normal singleton |
||
< |
<syntaxhighlight lang="elena">class Singleton |
||
{ |
{ |
||
object theField |
object theField; |
||
// ... |
// ... |
||
} |
} |
||
static singleton = |
static singleton = new Singleton();</syntaxhighlight> |
||
=={{header|EMal}}== |
|||
<syntaxhighlight lang="emal"> |
|||
type Singleton |
|||
model |
|||
text greeting |
|||
fun speak = void by block do writeLine(me.greeting + " I'm a singleton") end |
|||
end |
|||
Singleton instance |
|||
fun getInstance = Singleton by block |
|||
if instance == null do instance = Singleton() end |
|||
return instance |
|||
end |
|||
type SomeOtherType |
|||
Singleton s1 = Singleton.getInstance() |
|||
s1.greeting = "Hello" |
|||
Singleton s2 = Singleton.getInstance() |
|||
s2.greeting.append(", World!") |
|||
writeLine(s1 + " and " + s2 + " are the same object: " + (s1 == s2) + ", s2: " + s2.greeting) |
|||
s1.speak() # call instance method |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
§(0x02bf8098) and §(0x02bf8098) are the same object: ⊤, s2: Hello, World! |
|||
Hello, World! I'm a singleton |
|||
</pre> |
|||
=={{header|Epoxy}}== |
|||
<syntaxhighlight lang="epoxy">fn Singleton() |
|||
if this.self then return this.self cls |
|||
var new: {} |
|||
iter k,v as this._props do |
|||
new[k]:v |
|||
cls |
|||
this.self:new |
|||
return new |
|||
cls |
|||
Singleton._props: { |
|||
name: "Singleton", |
|||
fn setName(self,new) |
|||
self.name:new |
|||
cls, |
|||
} |
|||
var MySingleton: Singleton() |
|||
log(MySingleton == Singleton()) --true |
|||
log(MySingleton.name) --Singleton |
|||
var NewSingleton: Singleton() |
|||
NewSingleton>>setName("Test") |
|||
log(MySingleton.name) --Test</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
true |
|||
Singleton |
|||
Test |
|||
</pre> |
|||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
Erlang is not object-oriented, so there is no such thing as a singleton class. The singleton is something of an anti-pattern in Erlang, so if you are tempted to do this, there is probably a better architecture. If you do want something akin to a singleton, you start and register a process that maintains its state in a message loop and provides its state to anyone that wants it or needs to change it. Since this is done with message passing, it's safe for concurrent use. |
Erlang is not object-oriented, so there is no such thing as a singleton class. The singleton is something of an anti-pattern in Erlang, so if you are tempted to do this, there is probably a better architecture. If you do want something akin to a singleton, you start and register a process that maintains its state in a message loop and provides its state to anyone that wants it or needs to change it. Since this is done with message passing, it's safe for concurrent use. |
||
< |
<syntaxhighlight lang="erlang">-module(singleton). |
||
-export([get/0, set/1, start/0]). |
-export([get/0, set/1, start/0]). |
||
Line 774: | Line 1,010: | ||
From ! ok, |
From ! ok, |
||
loop(NewValue) |
loop(NewValue) |
||
end.</ |
end.</syntaxhighlight> |
||
Here is an example of how to use it (from the shell). It assumes singleton:start/0 was already called from the supervisor tree (as would be typical if you were using something like this). |
Here is an example of how to use it (from the shell). It assumes singleton:start/0 was already called from the supervisor tree (as would be typical if you were using something like this). |
||
< |
<syntaxhighlight lang="erlang">1> singleton:get(). |
||
not_set |
not_set |
||
2> singleton:set(apple). |
2> singleton:set(apple). |
||
Line 791: | Line 1,027: | ||
ok |
ok |
||
7> singleton:get(). |
7> singleton:get(). |
||
{ok,42}</ |
{ok,42}</syntaxhighlight> |
||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
< |
<syntaxhighlight lang="factor">USING: classes.singleton kernel io prettyprint ; |
||
IN: singleton-demo |
IN: singleton-demo |
||
SINGLETON: bar |
SINGLETON: bar |
||
GENERIC: foo ( obj -- ) |
GENERIC: foo ( obj -- ) |
||
M: bar foo drop "Hello!" print ;</ |
M: bar foo drop "Hello!" print ;</syntaxhighlight> |
||
( scratchpad ) bar foo |
( scratchpad ) bar foo |
||
Hello! |
Hello! |
||
Line 807: | Line 1,043: | ||
Works with any ANS Forth |
Works with any ANS Forth |
||
Needs the |
Needs the FMS2VT Forth extension located here: |
||
https://github.com/DouglasBHoffman/FMS2/tree/master/FMS2VT |
|||
http://soton.mpeforth.com/flag/fms/index.html |
|||
< |
<syntaxhighlight lang="forth">include FMS2VT.f |
||
\ A singleton is created by using normal Forth data |
\ A singleton is created by using normal Forth data |
||
Line 837: | Line 1,073: | ||
s1 printb \ => 9 |
s1 printb \ => 9 |
||
s2 printa \ => 4 |
s2 printa \ => 4 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
||
Line 843: | Line 1,079: | ||
From the Go standard library, sync.Once provides a way to ensure that some "step," effectively an initialization step, is performed no more than once even if it might be attempted from multiple concurrent goroutines. This capability might be considered similar to some mechanism ensuring that singleton constructor code is only run once. |
From the Go standard library, sync.Once provides a way to ensure that some "step," effectively an initialization step, is performed no more than once even if it might be attempted from multiple concurrent goroutines. This capability might be considered similar to some mechanism ensuring that singleton constructor code is only run once. |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 873: | Line 1,109: | ||
w.Wait() |
w.Wait() |
||
log.Println("after trying both, instance =", instance) |
log.Println("after trying both, instance =", instance) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 888: | Line 1,124: | ||
Because packages cannot be imported multiple times, data declared at package level will only ever have a single instance, and the package as a whole serves as a singleton. |
Because packages cannot be imported multiple times, data declared at package level will only ever have a single instance, and the package as a whole serves as a singleton. |
||
< |
<syntaxhighlight lang="go">package singlep |
||
// package level data declarations serve as singleton instance variables |
// package level data declarations serve as singleton instance variables |
||
Line 901: | Line 1,137: | ||
func F() int { |
func F() int { |
||
return Y - X |
return Y - X |
||
}</ |
}</syntaxhighlight> |
||
Example program using the package: |
Example program using the package: |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 914: | Line 1,150: | ||
fmt.Println(singlep.X, singlep.Y) |
fmt.Println(singlep.X, singlep.Y) |
||
fmt.Println(singlep.F()) |
fmt.Println(singlep.F()) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 925: | Line 1,161: | ||
This example combines the two previous concepts and also shows some additional concepts. It has packages imported with a "diamond" dependency. While both <code>red</code> and <code>blue</code> import <code>single</code>, only a single variable <code>color</code> will exist in memory. The <code>init()</code> mechanism shown above actually runs before <code>main()</code>. In contrast, the <code>sync.Once</code> mechanism can serve as constructor code after <code>main()</code> begins. |
This example combines the two previous concepts and also shows some additional concepts. It has packages imported with a "diamond" dependency. While both <code>red</code> and <code>blue</code> import <code>single</code>, only a single variable <code>color</code> will exist in memory. The <code>init()</code> mechanism shown above actually runs before <code>main()</code>. In contrast, the <code>sync.Once</code> mechanism can serve as constructor code after <code>main()</code> begins. |
||
< |
<syntaxhighlight lang="go">package single |
||
import ( |
import ( |
||
Line 948: | Line 1,184: | ||
once.Do(func() { color = c }) |
once.Do(func() { color = c }) |
||
log.Println("color initialized to", color) |
log.Println("color initialized to", color) |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="go">package red |
||
import ( |
import ( |
||
Line 960: | Line 1,196: | ||
log.Println("trying to set red") |
log.Println("trying to set red") |
||
single.SetColor("red") |
single.SetColor("red") |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="go">package blue |
||
import ( |
import ( |
||
Line 972: | Line 1,208: | ||
log.Println("trying to set blue") |
log.Println("trying to set blue") |
||
single.SetColor("blue") |
single.SetColor("blue") |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 996: | Line 1,232: | ||
} |
} |
||
log.Println(single.Color()) |
log.Println(single.Color()) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,009: | Line 1,245: | ||
=={{header|Groovy}}== |
=={{header|Groovy}}== |
||
< |
<syntaxhighlight lang="groovy">@Singleton |
||
class SingletonClass { |
class SingletonClass { |
||
Line 1,019: | Line 1,255: | ||
SingletonClass.instance.invokeMe() |
SingletonClass.instance.invokeMe() |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>invoking method of a singleton class</pre> |
<pre>invoking method of a singleton class</pre> |
||
Line 1,025: | Line 1,261: | ||
==Icon and {{header|Unicon}}== |
==Icon and {{header|Unicon}}== |
||
Icon is not object oriented, but Unicon supports O-O programming. |
Icon is not object oriented, but Unicon supports O-O programming. |
||
< |
<syntaxhighlight lang="unicon">class Singleton |
||
method print() |
method print() |
||
write("Hi there.") |
write("Hi there.") |
||
Line 1,037: | Line 1,273: | ||
Singleton().print() |
Singleton().print() |
||
Singleton().print() |
Singleton().print() |
||
end</ |
end</syntaxhighlight> |
||
This Unicon example uses a number of Icon features. |
This Unicon example uses a number of Icon features. |
||
Line 1,049: | Line 1,285: | ||
=={{header|Io}}== |
=={{header|Io}}== |
||
Io does not have globals. But it is easy to make singleton objects: |
Io does not have globals. But it is easy to make singleton objects: |
||
< |
<syntaxhighlight lang="io">Singleton := Object clone |
||
Singleton clone = Singleton</ |
Singleton clone = Singleton</syntaxhighlight> |
||
=={{header|J}}== |
=={{header|J}}== |
||
Line 1,060: | Line 1,296: | ||
===Thread-safe=== |
===Thread-safe=== |
||
[[wp:Double-checked locking]]; only use with Java 1.5+ |
[[wp:Double-checked locking]]; only use with Java 1.5+ |
||
< |
<syntaxhighlight lang="java">class Singleton |
||
{ |
{ |
||
private static Singleton myInstance; |
private static Singleton myInstance; |
||
Line 1,085: | Line 1,321: | ||
// Any other methods |
// Any other methods |
||
}</ |
}</syntaxhighlight> |
||
===Thread-Safe Lazy-Loaded=== |
===Thread-Safe Lazy-Loaded=== |
||
This is the [[wp:Initialization-on-demand holder idiom]]. |
This is the [[wp:Initialization-on-demand holder idiom]]. |
||
< |
<syntaxhighlight lang="java">public class Singleton { |
||
private Singleton() { |
private Singleton() { |
||
// Constructor code goes here. |
// Constructor code goes here. |
||
Line 1,101: | Line 1,337: | ||
return LazyHolder.INSTANCE; |
return LazyHolder.INSTANCE; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
===Thread-Safe Using Enum === |
|||
Enums in Java are fully-fledged classes with specific instances, and are an idiomatic way to create singletons. |
|||
<syntaxhighlight lang="java">public enum Singleton { |
|||
INSTANCE; |
|||
// Fields, constructors and methods... |
|||
private int value; |
|||
Singleton() { |
|||
value = 0; |
|||
} |
|||
public int getValue() { |
|||
return value; |
|||
} |
|||
public void setValue(int value) { |
|||
this.value = value; |
|||
} |
|||
}</syntaxhighlight> |
|||
===Non-Thread-Safe=== |
===Non-Thread-Safe=== |
||
< |
<syntaxhighlight lang="java">class Singleton |
||
{ |
{ |
||
private static Singleton myInstance; |
private static Singleton myInstance; |
||
Line 1,123: | Line 1,377: | ||
// Any other methods |
// Any other methods |
||
}</ |
}</syntaxhighlight> |
||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
< |
<syntaxhighlight lang="javascript">function Singleton() { |
||
if(Singleton._instance) return Singleton._instance; |
if(Singleton._instance) return Singleton._instance; |
||
this.set(""); |
this.set(""); |
||
Line 1,145: | Line 1,399: | ||
c.append("!!!"); |
c.append("!!!"); |
||
document.write( (new Singleton()).get() );</ |
document.write( (new Singleton()).get() );</syntaxhighlight> |
||
=={{header|Julia}}== |
|||
Julia allows singletons as type declarations without further specifiers. There can be only one instance of such a type, and if more than one variable is bound to such a type they are actually all bound to the same instance in memory: |
|||
<syntaxhighlight lang="julia"> |
|||
struct IAmaSingleton end |
|||
x = IAmaSingleton() |
|||
y = IAmaSingleton() |
|||
println("x == y is $(x == y) and x === y is $(x === y).") |
|||
</syntaxhighlight> |
|||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
Kotlin has built-in support for singletons via object declarations. To refer to the singleton, we simply use its name which can be any valid identifier other than a keyword: |
Kotlin has built-in support for singletons via object declarations. To refer to the singleton, we simply use its name which can be any valid identifier other than a keyword: |
||
<lang |
<syntaxhighlight lang="scala">// version 1.1.2 |
||
object Singleton { |
object Singleton { |
||
Line 1,157: | Line 1,422: | ||
fun main(args: Array<String>) { |
fun main(args: Array<String>) { |
||
Singleton.speak() |
Singleton.speak() |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,163: | Line 1,428: | ||
I am a singleton |
I am a singleton |
||
</pre> |
</pre> |
||
=={{header|M2000 Interpreter}}== |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
Module CheckSingleton { |
|||
\\ singleton |
|||
\\ pointers and static groups are the same object because |
|||
\\ each one has a pointer to same state (a tuple) |
|||
\\ but from outside we do the miracle to have a static group to act as a pointer |
|||
\\ We need a lambda function to hold the pointer to Singleton as closure |
|||
Global One=lambda M=pointer() (aValue=0)-> { |
|||
If M is type null then |
|||
\\ one time happen |
|||
Group Singleton { |
|||
Type:One |
|||
Private: |
|||
state=(aValue,) |
|||
Public: |
|||
module Add (x) { |
|||
.state+=x |
|||
} |
|||
Set {Drop} |
|||
Value { |
|||
=.state#val(0) |
|||
} |
|||
} |
|||
M->group(Singleton) |
|||
end if |
|||
\\ return M which is a pointer |
|||
=M |
|||
} |
|||
K=One(100) |
|||
Print Eval(K)=100 |
|||
M=One() |
|||
Print Eval(M)=100 |
|||
Print K is M = true |
|||
Print K is type One = true |
|||
K=>add 500 |
|||
Print eval(K)=600 |
|||
\\ copy K to Z (no pointer to Z, Z is named group) |
|||
Z=Group(K) |
|||
Print eval(z)=600, z=600 |
|||
Z.add 1000 |
|||
Print Z=1600, Eval(M)=1600, Eval(K)=1600 |
|||
\\ push a copy of Z, but state is pointer so we get a copy of a pointer |
|||
Push Group(Z) |
|||
Read beta |
|||
Beta.add 1000 |
|||
Print Z=2600, Eval(M)=2600, Eval(K)=2600 |
|||
\\ convert pointer to group (a copy of group) |
|||
group delta=One() |
|||
delta.add 1000 |
|||
Print Z=3600, beta=3600, delta=3600, Eval(M)=3600, Eval(K)=3600 |
|||
\\ M and K are pointers to groups |
|||
M=>add 400 |
|||
Print Z=4000, beta=4000, delta=4000, Eval(M)=4000, Eval(K)=4000 |
|||
} |
|||
CheckSingleton |
|||
</syntaxhighlight> |
|||
=={{header|Lasso}}== |
=={{header|Lasso}}== |
||
Line 1,170: | Line 1,494: | ||
===Server wide singleton=== |
===Server wide singleton=== |
||
< |
<syntaxhighlight lang="lasso">// Define the thread if it doesn't exist |
||
// New definition supersede any current threads. |
// New definition supersede any current threads. |
||
Line 1,186: | Line 1,510: | ||
#b->switch = 'b' |
#b->switch = 'b' |
||
#a->switch // b</ |
#a->switch // b</syntaxhighlight> |
||
===Thread level singleton=== |
===Thread level singleton=== |
||
< |
<syntaxhighlight lang="lasso">// Define thread level singleton |
||
define singleton => type { |
define singleton => type { |
||
Line 1,205: | Line 1,529: | ||
#b->switch = 'b' |
#b->switch = 'b' |
||
#a->switch // b</ |
#a->switch // b</syntaxhighlight> |
||
=={{header|Latitude}}== |
|||
Latitude objects are prototypes, so any new object can be treated as a singleton by simply not cloning it. For added security, one can always override <code>clone</code> to make it clear that the object should not be cloned, but this is generally overkill. |
|||
<syntaxhighlight lang="latitude">Singleton ::= Object clone tap { |
|||
self id := 0. |
|||
self newID := { |
|||
self id := self id + 1. |
|||
}. |
|||
self clone := { |
|||
err ArgError clone tap { self message := "Singleton object!". } throw. |
|||
}. |
|||
}. |
|||
println: Singleton newID. ; 1 |
|||
println: Singleton newID. ; 2 |
|||
println: Singleton newID. ; 3</syntaxhighlight> |
|||
=={{header|Lingo}}== |
=={{header|Lingo}}== |
||
In Lingo a Singleton class can be implemented like this: |
In Lingo a Singleton class can be implemented like this: |
||
< |
<syntaxhighlight lang="lingo">-- parent script "SingletonDemo" |
||
property _instance |
property _instance |
||
Line 1,230: | Line 1,570: | ||
me._someProperty = me._someProperty + x |
me._someProperty = me._someProperty + x |
||
return me._someProperty |
return me._someProperty |
||
end</ |
end</syntaxhighlight> |
||
=={{header|Logtalk}}== |
=={{header|Logtalk}}== |
||
Logtalk supports both classes and prototypes. A prototype is a much simpler solution for defining a singleton object than defining a class with only an instance. |
Logtalk supports both classes and prototypes. A prototype is a much simpler solution for defining a singleton object than defining a class with only an instance. |
||
< |
<syntaxhighlight lang="logtalk">:- object(singleton). |
||
:- public(value/1). |
:- public(value/1). |
||
Line 1,249: | Line 1,589: | ||
state(0). |
state(0). |
||
:- end_object.</ |
:- end_object.</syntaxhighlight> |
||
A simple usage example after compiling and loading the code above: |
A simple usage example after compiling and loading the code above: |
||
< |
<syntaxhighlight lang="logtalk">| ?- singleton::value(Value). |
||
Value = 0 |
Value = 0 |
||
yes |
yes |
||
Line 1,257: | Line 1,597: | ||
| ?- singleton::(set_value(1), value(Value)). |
| ?- singleton::(set_value(1), value(Value)). |
||
Value = 1 |
Value = 1 |
||
yes</ |
yes</syntaxhighlight> |
||
=={{header|NetRexx}}== |
=={{header|NetRexx}}== |
||
Uses a static field to avoid synchronization problems and the ''flawed'' "double-checked locking" idiom in JVMs. See [http://www.ibm.com/developerworks/java/library/j-dcl/index.html www.ibm.com/developerworks/java/library/j-dcl/index.html] for a detailed explanation. |
Uses a static field to avoid synchronization problems and the ''flawed'' "double-checked locking" idiom in JVMs. See [http://www.ibm.com/developerworks/java/library/j-dcl/index.html www.ibm.com/developerworks/java/library/j-dcl/index.html] for a detailed explanation. |
||
< |
<syntaxhighlight lang="netrexx">/* NetRexx */ |
||
options replace format comments java crossref symbols binary |
options replace format comments java crossref symbols binary |
||
Line 1,359: | Line 1,699: | ||
return info |
return info |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 1,389: | Line 1,729: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
In the file <code>singleton.nim</code> we don't export the type, so new objects can't be created: |
In the file <code>singleton.nim</code> we don't export the type, so new objects can't be created: |
||
< |
<syntaxhighlight lang="nim">type Singleton = object # Singleton* would export |
||
foo*: int |
foo*: int |
||
var single* = Singleton(foo: 0)</ |
var single* = Singleton(foo: 0)</syntaxhighlight> |
||
Then in another file we can use the singleton object: |
Then in another file we can use the singleton object: |
||
< |
<syntaxhighlight lang="nim">import singleton |
||
single.foo = 12 |
single.foo = 12 |
||
echo single.foo</ |
echo single.foo</syntaxhighlight> |
||
=={{header|Objeck}}== |
=={{header|Objeck}}== |
||
< |
<syntaxhighlight lang="objeck">class Singleton { |
||
@singleton : static : Singleton; |
@singleton : static : Singleton; |
||
Line 1,417: | Line 1,757: | ||
... |
... |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Objective-C}}== |
=={{header|Objective-C}}== |
||
===Non-Thread-Safe=== |
===Non-Thread-Safe=== |
||
(Using Cocoa/OpenStep's NSObject as a base class) |
(Using Cocoa/OpenStep's NSObject as a base class) |
||
< |
<syntaxhighlight lang="objc">// SomeSingleton.h |
||
@interface SomeSingleton : NSObject |
@interface SomeSingleton : NSObject |
||
{ |
{ |
||
Line 1,430: | Line 1,770: | ||
+ (SomeSingleton *)sharedInstance; |
+ (SomeSingleton *)sharedInstance; |
||
@end</ |
@end</syntaxhighlight> |
||
< |
<syntaxhighlight lang="objc">// SomeSingleton.m |
||
@implementation SomeSingleton |
@implementation SomeSingleton |
||
Line 1,469: | Line 1,809: | ||
} |
} |
||
@end</ |
@end</syntaxhighlight> |
||
===Thread-Safe=== |
===Thread-Safe=== |
||
Same as above except: |
Same as above except: |
||
< |
<syntaxhighlight lang="objc">+ (SomeSingleton *) sharedInstance |
||
{ |
{ |
||
static SomeSingleton *sharedInstance = nil; |
static SomeSingleton *sharedInstance = nil; |
||
Line 1,482: | Line 1,822: | ||
} |
} |
||
return sharedInstance; |
return sharedInstance; |
||
}</ |
}</syntaxhighlight> |
||
===With GCD=== |
===With GCD=== |
||
Same as above except: |
Same as above except: |
||
< |
<syntaxhighlight lang="objc">+ (SomeSingleton *) sharedInstance |
||
{ |
{ |
||
static SomeSingleton *sharedInstance = nil; |
static SomeSingleton *sharedInstance = nil; |
||
Line 1,494: | Line 1,834: | ||
}); |
}); |
||
return sharedInstance; |
return sharedInstance; |
||
}</ |
}</syntaxhighlight> |
||
===With class methods=== |
===With class methods=== |
||
Line 1,500: | Line 1,840: | ||
In other words, here the class object serves as the singleton object. The "singleton class" is the metaclass of the class. The downside of this approach is that the "singleton class" (the metaclass of the class) cannot be made to explicitly inherit from a class of the user's choice, or implement a protocol of the user's choice. Also, there is no way to prevent subclasses of the class from being made, thus effectively creating "multiple instances" of the singleton class. Also, one cannot declare properties on the singleton (the class object). |
In other words, here the class object serves as the singleton object. The "singleton class" is the metaclass of the class. The downside of this approach is that the "singleton class" (the metaclass of the class) cannot be made to explicitly inherit from a class of the user's choice, or implement a protocol of the user's choice. Also, there is no way to prevent subclasses of the class from being made, thus effectively creating "multiple instances" of the singleton class. Also, one cannot declare properties on the singleton (the class object). |
||
=={{header|Oforth}}== |
=={{header|Oforth}}== |
||
Line 1,512: | Line 1,851: | ||
For instance, this Sequence class creates instances that increment an integer and send it. If a task tries to get the next value before it is incremented, it will wait until the channel is no more empty and holds the new value. This won't work if the value is a mutable value (you will get an exception if you try to send a mutable object into channel). A mutable object can't be shared between tasks. Here we send a new integer each time. |
For instance, this Sequence class creates instances that increment an integer and send it. If a task tries to get the next value before it is incremented, it will wait until the channel is no more empty and holds the new value. This won't work if the value is a mutable value (you will get an exception if you try to send a mutable object into channel). A mutable object can't be shared between tasks. Here we send a new integer each time. |
||
< |
<syntaxhighlight lang="oforth">Object Class new: Sequence(channel) |
||
Sequence method: initialize(initialValue) |
Sequence method: initialize(initialValue) |
||
Channel newSize(1) := channel |
Channel newSize(1) := channel |
||
@channel send(initialValue) drop ; |
@channel send(initialValue) drop ; |
||
Sequence method: nextValue @channel receive dup 1 + @channel send drop ;</ |
Sequence method: nextValue @channel receive dup 1 + @channel send drop ;</syntaxhighlight> |
||
Usage : |
Usage : |
||
< |
<syntaxhighlight lang="oforth">import: parallel |
||
: testSequence |
: testSequence |
||
| s i | |
| s i | |
||
Sequence new(0) ->s |
Sequence new(0) ->s |
||
100 loop: i [ #[ s nextValue println ] & ] ;</ |
100 loop: i [ #[ s nextValue println ] & ] ;</syntaxhighlight> |
||
=={{header|ooRexx}}== |
=={{header|ooRexx}}== |
||
<syntaxhighlight lang="oorexx"> |
|||
<lang ooRexx> |
|||
a = .singleton~new |
a = .singleton~new |
||
b = .singleton~new |
b = .singleton~new |
||
Line 1,561: | Line 1,900: | ||
a singleton. |
a singleton. |
||
::attribute foo |
::attribute foo |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|OxygenBasic}}== |
|||
The singleton contains static members only. It may be instantiated any number of times, but the members will all be shared. |
|||
<lang oxygenbasic> |
|||
class singleton |
|||
static sys a,b,c |
|||
static string s,t,u |
|||
static double x,y,z |
|||
end class |
|||
'TEST |
|||
'==== |
|||
singleton A |
|||
singleton B |
|||
A.c=3 |
|||
print B.c 'result 3 |
|||
print sizeof B 'result 0 |
|||
</lang> |
|||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
Singleton is not a common pattern in Oz programs. It can be implemented by limiting the scope of the class definition such that only the <code>GetInstance</code> function has access to it. |
Singleton is not a common pattern in Oz programs. It can be implemented by limiting the scope of the class definition such that only the <code>GetInstance</code> function has access to it. |
||
< |
<syntaxhighlight lang="oz">declare |
||
local |
local |
||
class Singleton |
class Singleton |
||
Line 1,602: | Line 1,922: | ||
end |
end |
||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
This will work as long as all functors are linked with <code>import</code> statements. If you use multiple calls to <code>Module.link</code> instead, you will get multiple instances of the "Singleton". |
This will work as long as all functors are linked with <code>import</code> statements. If you use multiple calls to <code>Module.link</code> instead, you will get multiple instances of the "Singleton". |
||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<syntaxhighlight lang="perl">package Singleton; |
||
use strict; |
use strict; |
||
use warnings; |
use warnings; |
||
Line 1,634: | Line 1,954: | ||
my $s2 = Singleton->new; |
my $s2 = Singleton->new; |
||
printf "name: %s, ref: %s\n", $s2->name, $s2;</ |
printf "name: %s, ref: %s\n", $s2->name, $s2;</syntaxhighlight> |
||
=={{header| |
=={{header|Phix}}== |
||
{{libheader|Phix/Class}} |
|||
<lang Perl6>class Singleton { |
|||
Not really any special handling for singletons in Phix, but you can do something like this, |
|||
# We create a lexical variable in the class block that holds our single instance. |
|||
or keep check() private and invoke it internally from a few critical routines. |
|||
my Singleton $instance = Singleton.bless; # You can add initialization arguments here. |
|||
Needs 0.8.1+ |
|||
method new {!!!} # Singleton.new dies. |
|||
<syntaxhighlight lang="phix">-- <separate include file> |
|||
method instance { $instance; } |
|||
object chk = NULL |
|||
}</lang> |
|||
class singleton |
|||
public procedure check() |
|||
if chk==NULL then |
|||
chk = this |
|||
elsif this!=chk then |
|||
?9/0 |
|||
end if |
|||
?"ok" |
|||
end procedure |
|||
end class |
|||
global singleton s = new() |
|||
--global singleton s2 = new() |
|||
-- </separate include file> |
|||
s.check() |
|||
--s2.check() -- dies</syntaxhighlight> |
|||
While all classes are technically global in the sense that builtins\structs.e knows all about them, the |
|||
implicit associated user defined type is by default private (ie w/o "global" in front of the class def). |
|||
The above separate file prohibits the use of (other) <code>singleton s = new()</code> everywhere, however |
|||
<code>class s = new("singleton")</code> could still be used anywhere, and that way get duplicates. |
|||
One obvious alternative (of no special merit imo) might be to replace that global singleton s with: |
|||
<syntaxhighlight lang="phix">global function get_singleton() |
|||
if chk==NULL then |
|||
chk = new("singleton") |
|||
end if |
|||
return chk |
|||
end function</syntaxhighlight> |
|||
Technically, builtins/struct.e looks like it could easily be modified to support something very similar |
|||
to the Python Borg pattern, by appropriately sharing cdx/tid in new(). However it would be even better |
|||
to share the whole delete_routine()'d res, and that would probably be best achieved by setting a new |
|||
flag, say S_SINGLETON or S_STATIC, alongside and triggered via similar syntax to S_ABSTRACT/S_NULLABLE. |
|||
Maybe. |
|||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
< |
<syntaxhighlight lang="php">class Singleton { |
||
protected static $instance = null; |
protected static $instance = null; |
||
public $test_var; |
public $test_var; |
||
Line 1,665: | Line 2,018: | ||
echo $bar->test_var; //Prints 'One' |
echo $bar->test_var; //Prints 'One' |
||
$fail = new Singleton(); //Fatal error</ |
$fail = new Singleton(); //Fatal error</syntaxhighlight> |
||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
As there is no physical difference between classes and objects, we can use the |
As there is no physical difference between classes and objects, we can use the |
||
class symbol itself. |
class symbol itself. |
||
< |
<syntaxhighlight lang="picolisp">(class +Singleton) |
||
(dm message1> () |
(dm message1> () |
||
Line 1,676: | Line 2,029: | ||
(dm message2> () |
(dm message2> () |
||
(prinl "This is method 2 on " This) )</ |
(prinl "This is method 2 on " This) )</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>: (message1> '+Singleton) |
<pre>: (message1> '+Singleton) |
||
Line 1,687: | Line 2,040: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
===per Borg Design=== |
|||
In Python we use the [http://code.activestate.com/recipes/66531/ Borg pattern] to share state between instances rather than concentrate on identity. |
In Python we use the [http://code.activestate.com/recipes/66531/ Borg pattern] to share state between instances rather than concentrate on identity. |
||
Every instance of the Borg class will share the same state: |
Every instance of the Borg class will share the same state: |
||
< |
<syntaxhighlight lang="python">>>> class Borg(object): |
||
__state = {} |
__state = {} |
||
def __init__(self): |
def __init__(self): |
||
Line 1,708: | Line 2,062: | ||
>>> b1.datum is b2.datum |
>>> b1.datum is b2.datum |
||
True |
True |
||
>>> # For any datum!</ |
>>> # For any datum!</syntaxhighlight> |
||
===per MetaClass/AbstractBaseClass=== |
|||
An approximation of the singleton can be made using only class attributes to store data instead of the instance attributes, providing at least one abstract instance method (class can not be instantiated then) and making the rest of the methods being class methods. E.g. |
An approximation of the singleton can be made using only class attributes to store data instead of the instance attributes, providing at least one abstract instance method (class can not be instantiated then) and making the rest of the methods being class methods. E.g. |
||
< |
<syntaxhighlight lang="python"> |
||
import abc |
import abc |
||
Line 1,742: | Line 2,098: | ||
Singleton.printSelf() |
Singleton.printSelf() |
||
print Singleton.state |
print Singleton.state |
||
</syntaxhighlight> |
|||
</lang> |
|||
When executed this code should print out the following:<br> |
When executed this code should print out the following:<br> |
||
<br> |
<br> |
||
Line 1,753: | Line 2,109: | ||
So, instantiation is not possible. Only a single object is available, and it behaves as a singleton. |
So, instantiation is not possible. Only a single object is available, and it behaves as a singleton. |
||
=={{header|PureBasic}}== |
|||
===Native version=== |
|||
Thread safe version. |
|||
<lang PureBasic>Global SingletonSemaphore=CreateSemaphore(1) |
|||
Interface OO_Interface ; Interface for any value of this type |
|||
Get.i() |
|||
Set(Value.i) |
|||
Destroy() |
|||
EndInterface |
|||
===per MetaClass=== |
|||
Structure OO_Structure ; The *VTable structure |
|||
Get.i |
|||
Set.i |
|||
Destroy.i |
|||
EndStructure |
|||
Structure OO_Var |
|||
*VirtualTable.OO_Structure |
|||
Value.i |
|||
EndStructure |
|||
<syntaxhighlight lang="python"> |
|||
Procedure OO_Get(*Self.OO_Var) |
|||
class Singleton(type): |
|||
ProcedureReturn *Self\Value |
|||
_instances = {} |
|||
EndProcedure |
|||
def __call__(cls, *args, **kwargs): |
|||
if cls not in cls._instances: |
|||
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) |
|||
return cls._instances[cls] |
|||
class Logger(object): |
|||
Procedure OO_Set(*Self.OO_Var, n) |
|||
__metaclass__ = Singleton |
|||
*Self\Value = n |
|||
</syntaxhighlight> |
|||
EndProcedure |
|||
or in Python3 |
|||
Procedure CreateSingleton() |
|||
If TrySemaphore(SingletonSemaphore) |
|||
*p.OO_Var = AllocateMemory(SizeOf(OO_Var)) |
|||
If *p |
|||
*p\VirtualTable = ?VTable |
|||
EndIf |
|||
EndIf |
|||
ProcedureReturn *p |
|||
EndProcedure |
|||
Procedure OO_Destroy(*Self.OO_Var) |
|||
FreeMemory(*Self) |
|||
SignalSemaphore(SingletonSemaphore) |
|||
EndProcedure |
|||
<syntaxhighlight lang="python"> |
|||
DataSection |
|||
class Logger(metaclass=Singleton): |
|||
VTable: |
|||
pass |
|||
Data.i @OO_Get() |
|||
</syntaxhighlight> |
|||
Data.i @OO_Set() |
|||
Data.i @OO_Destroy() |
|||
EndDataSection</lang> |
|||
===Simple OOP extension=== |
|||
Using the open-source precompiler [http://www.development-lounge.de/viewtopic.php?t=5915 SimpleOOP]. |
|||
<lang PureBasic>Singleton Class Demo |
|||
BeginPrivate |
|||
Name$ |
|||
X.i |
|||
EndPrivate |
|||
Public Method Init(Name$) |
|||
This\Name$ = Name$ |
|||
EndMethod |
|||
Public Method GetX() |
|||
MethodReturn This\X |
|||
EndMethod |
|||
Public Method SetX(n) |
|||
This\X = n |
|||
EndMethod |
|||
Public Method Hello() |
|||
MessageRequester("Hello!", "I'm "+This\Name$) |
|||
EndMethod |
|||
EndClass</lang> |
|||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
Singletons are not very useful in Racket, because functions that use module state are more straightforward. However, classes are first class values, and therefore they follow the same rules as all other bindings. For example, a class can be made and instantiated but not provided to client files: |
Singletons are not very useful in Racket, because functions that use module state are more straightforward. However, classes are first class values, and therefore they follow the same rules as all other bindings. For example, a class can be made and instantiated but not provided to client files: |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
(provide instance) |
(provide instance) |
||
Line 1,840: | Line 2,144: | ||
(super-new))) |
(super-new))) |
||
(define instance (new singleton%)) |
(define instance (new singleton%)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Or better, not name the class at all: |
Or better, not name the class at all: |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
(provide instance) |
(provide instance) |
||
Line 1,850: | Line 2,154: | ||
(define/public (foo) 123) |
(define/public (foo) 123) |
||
(super-new)))) |
(super-new)))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
<syntaxhighlight lang="raku" line>class Singleton { |
|||
# We create a lexical variable in the class block that holds our single instance. |
|||
my Singleton $instance = Singleton.bless; # You can add initialization arguments here. |
|||
method new {!!!} # Singleton.new dies. |
|||
method instance { $instance; } |
|||
}</syntaxhighlight> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
< |
<syntaxhighlight lang="ruby">require 'singleton' |
||
class MySingleton |
class MySingleton |
||
include Singleton |
include Singleton |
||
Line 1,861: | Line 2,174: | ||
a = MySingleton.instance # instance is only created the first time it is requested |
a = MySingleton.instance # instance is only created the first time it is requested |
||
b = MySingleton.instance |
b = MySingleton.instance |
||
puts a.equal?(b) # outputs "true"</ |
puts a.equal?(b) # outputs "true"</syntaxhighlight> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
The '''object''' construct in Scala is a singleton. |
The '''object''' construct in Scala is a singleton. |
||
< |
<syntaxhighlight lang="scala">object Singleton { |
||
// any code here gets executed as if in a constructor |
// any code here gets executed as if in a constructor |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
< |
<syntaxhighlight lang="ruby">class Singleton(name) { |
||
static instance; |
static instance; |
||
Line 1,890: | Line 2,203: | ||
s2.name = 'bar'; # change name in s2 |
s2.name = 'bar'; # change name in s2 |
||
say s1.name; #=> 'bar'</ |
say s1.name; #=> 'bar'</syntaxhighlight> |
||
=={{header|Slate}}== |
=={{header|Slate}}== |
||
Clones of Oddball themselves may not be cloned. |
Clones of Oddball themselves may not be cloned. |
||
Methods and slots may still be defined on them: |
Methods and slots may still be defined on them: |
||
< |
<syntaxhighlight lang="slate">define: #Singleton &builder: [Oddball clone]</syntaxhighlight> |
||
=={{header|Smalltalk}}== |
=={{header|Smalltalk}}== |
||
< |
<syntaxhighlight lang="smalltalk"> |
||
SomeClass class>>sharedInstance |
SomeClass class>>sharedInstance |
||
SharedInstance ifNil: [SharedInstance := self basicNew initialize]. |
SharedInstance ifNil: [SharedInstance := self basicNew initialize]. |
||
^ SharedInstance |
^ SharedInstance |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
< |
<syntaxhighlight lang="swift"> |
||
class SingletonClass { |
class SingletonClass { |
||
Line 1,919: | Line 2,232: | ||
// Usage |
// Usage |
||
let sharedObject = SingletonClass.sharedInstance |
let sharedObject = SingletonClass.sharedInstance |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
Line 1,925: | Line 2,238: | ||
ref http://wiki.tcl.tk/21595 |
ref http://wiki.tcl.tk/21595 |
||
< |
<syntaxhighlight lang="tcl">package require TclOO |
||
# This is a metaclass, a class that defines the behavior of other classes |
# This is a metaclass, a class that defines the behavior of other classes |
||
Line 1,945: | Line 2,258: | ||
return [incr count] |
return [incr count] |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Demonstrating in an interactive shell: |
Demonstrating in an interactive shell: |
||
< |
<syntaxhighlight lang="tcl">% set a [example new] |
||
::oo::Obj20 |
::oo::Obj20 |
||
% set b [example new] ;# note how this returns the same object name |
% set b [example new] ;# note how this returns the same object name |
||
Line 1,960: | Line 2,273: | ||
3 |
3 |
||
% $b counter |
% $b counter |
||
4</ |
4</syntaxhighlight> |
||
=={{header|Tern}}== |
|||
Tern has built-in support for singletons via module declarations. |
|||
<syntaxhighlight lang="tern">module Singleton { |
|||
speak() { |
|||
println("I am a singleton"); |
|||
} |
|||
} |
|||
Singleton.speak();</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
I am a singleton |
|||
</pre> |
|||
=={{header|TXR}}== |
|||
<syntaxhighlight lang="txrlisp">;; Custom (:singleton) clause which adds behavior to a class |
|||
;; asserting against multiple instantiation. |
|||
(define-struct-clause :singleton () |
|||
^((:static inst-count 0) |
|||
(:postinit (me) |
|||
(assert (<= (inc me.inst-count) 1))))) |
|||
(defstruct singleton-one () |
|||
(:singleton) |
|||
(:method speak (me) |
|||
(put-line "I am singleton-one"))) |
|||
(defstruct singleton-two () |
|||
(:singleton) |
|||
(:method speak (me) |
|||
(put-line "I am singleton-two"))) |
|||
;; Test |
|||
;; Global singleton |
|||
(defvarl s1 (new singleton-one)) |
|||
;; Local singleton in function (like static in C) |
|||
;; load-time evaluates once. |
|||
(defun fn () |
|||
(let ((s2 (load-time (new singleton-two)))) |
|||
s2.(speak))) |
|||
s1.(speak) |
|||
(fn) ;; multiple calls to fn don't re-instantiate singleton-two |
|||
(fn) |
|||
(put-line "so far, so good") |
|||
(new singleton-two) ;; assertion gooes off</syntaxhighlight> |
|||
{{out}} |
|||
<pre>I am singleton-one |
|||
I am singleton-two |
|||
I am singleton-two |
|||
so far, so good |
|||
txr: unhandled exception of type assert: |
|||
txr: assertion (<= (inc me.inst-count) |
|||
1) failed in singleton.tl:6 |
|||
txr: during evaluation at singleton.tl:6 of form (sys:rt-assert-fail "singleton.tl" |
|||
6 '(<= (inc me.inst-count) |
|||
1))</pre> |
|||
=={{header|Vala}}== |
=={{header|Vala}}== |
||
< |
<syntaxhighlight lang="vala">public class Singleton : Object { |
||
static Singleton? instance; |
static Singleton? instance; |
||
Line 1,986: | Line 2,364: | ||
print("Equal.\n"); |
print("Equal.\n"); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Wren}}== |
|||
Although it's possible to create a singleton in Wren, you have to rely on no one calling the 'private' constructor directly. This is because there is currently no way to create a private method in Wren - all you can do is to suffix the name with an underscore to indicate by convention it's for internal use only. |
|||
In practice, it's unlikely anyone would bother; they'd just create a class with static methods and/or fields only which is effectively a singleton as there's only ever a single instance of a static field. |
|||
<syntaxhighlight lang="wren">class Singleton { |
|||
// Returns the singleton. If it hasn't been created, creates it first. |
|||
static instance { __instance == null ? __instance = Singleton.new_() : __instance } |
|||
// Private constructor. |
|||
construct new_() {} |
|||
// instance method |
|||
speak() { System.print("I'm a singleton.") } |
|||
} |
|||
var s1 = Singleton.instance |
|||
var s2 = Singleton.instance |
|||
System.print("s1 and s2 are same object = %(Object.same(s1, s2))") |
|||
s1.speak() // call instance method</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
s1 and s2 are same object = true |
|||
I'm a singleton. |
|||
</pre> |
|||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
A class declared static only has one instance, ever. |
A class declared static only has one instance, ever. |
||
However, a class with the same name & structure could be created in another scope. |
However, a class with the same name & structure could be created in another scope. |
||
< |
<syntaxhighlight lang="zkl">class [static] Borg{ var v } |
||
b1 := Borg; b2 := Borg(); |
b1 := Borg; b2 := Borg(); |
||
b1 == b2 //--> True |
b1 == b2 //--> True |
||
b1.v=123; b2.v.println(); //--> 123</ |
b1.v=123; b2.v.println(); //--> 123</syntaxhighlight> |
||
{{omit from|6502 Assembly}} |
|||
{{omit from|68000 Assembly}} |
|||
{{omit from|8086 Assembly}} |
|||
{{omit from|ARM Assembly}} |
|||
{{omit from|AWK}} |
{{omit from|AWK}} |
||
{{omit from|GAP}} |
{{omit from|GAP}} |
||
Line 2,004: | Line 2,412: | ||
{{omit from|Mathematica}} |
{{omit from|Mathematica}} |
||
{{omit from|Maxima}} |
{{omit from|Maxima}} |
||
{{omit from|Minimal BASIC|Does not have user-defined data structures or objects.}} |
|||
{{omit from|Metafont}} |
{{omit from|Metafont}} |
||
{{omit from|Nascom BASIC|Does not have user-defined data structures or objects.}} |
|||
{{omit from|OCaml}} |
{{omit from|OCaml}} |
||
{{omit from|Octave}} |
{{omit from|Octave}} |
||
{{omit from|Palo Alto Tiny BASIC|Does not have user-defined data structures or objects.}} |
|||
{{omit from|PARI/GP}} |
{{omit from|PARI/GP}} |
||
{{omit from|PL/0|Does not have user-defined data structures or objects.}} |
|||
{{omit from|plainTeX}} |
{{omit from|plainTeX}} |
||
{{omit from|Retro|No OOP}} |
{{omit from|Retro|No OOP}} |
||
{{omit from|Standard ML}} |
|||
{{omit from|TI-83 BASIC}} |
{{omit from|TI-83 BASIC}} |
||
{{omit from|TI-89 BASIC|Does not have user-defined data structures or objects.}} |
{{omit from|TI-89 BASIC|Does not have user-defined data structures or objects.}} |
||
{{omit from|Tiny BASIC|Does not have user-defined data structures or objects.}} |
|||
{{omit from|x86 Assembly}} |
|||
{{omit from|Z80 Assembly}} |
|||
{{omit from|ZX Spectrum Basic|Does not have user-defined data structures or objects.}} |
{{omit from|ZX Spectrum Basic|Does not have user-defined data structures or objects.}} |
Latest revision as of 14:43, 24 April 2024
You are encouraged to solve this task according to the task description, using any language you may know.
A Global Singleton is a class of which only one instance exists within a program.
Any attempt to use non-static members of the class involves performing operations on this one instance.
ActionScript
package
{
public class Singleton
{
private static var instance:Singleton;
// ActionScript does not allow private or protected constructors.
public function Singleton(enforcer:SingletonEnforcer) {
}
public static function getInstance():Singleton {
if (instance == null) instance = new Singleton(new SingletonEnforcer());
return instance;
}
}
}
internal class SingletonEnforcer {}
Ada
Non Thread Safe
package Global_Singleton is
procedure Set_Data (Value : Integer);
function Get_Data return Integer;
private
type Instance_Type is record
-- Define instance data elements
Data : Integer := 0;
end record;
Instance : Instance_Type;
end Global_Singleton;
package body Global_Singleton is
--------------
-- Set_Data --
--------------
procedure Set_Data (Value : Integer) is
begin
Instance.Data := Value;
end Set_Data;
--------------
-- Get_Data --
--------------
function Get_Data return Integer is
begin
return Instance.Data;
end Get_Data;
end Global_Singleton;
Thread Safe
package Protected_Singleton is
procedure Set_Data (Value : Integer);
function Get_Data return Integer;
private
protected Instance is
procedure Set(Value : Integer);
function Get return Integer;
private
Data : Integer := 0;
end Instance_Type;
end Protected_Singleton;
package body Protected_Singleton is
--------------
-- Set_Data --
--------------
procedure Set_Data (Value : Integer) is
begin
Instance.Set(Value);
end Set_Data;
--------------
-- Get_Data --
--------------
function Get_Data return Integer is
begin
return Instance.Get;
end Get_Data;
--------------
-- Instance --
--------------
protected body Instance is
---------
-- Set --
---------
procedure Set (Value : Integer) is
begin
Data := Value;
end Set;
---------
-- Get --
---------
function Get return Integer is
begin
return Data;
end Get;
end Instance;
end Protected_Singleton;
AutoHotkey
Translation of python borg pattern
b1 := borg()
b2 := borg()
msgbox % "b1 is b2? " . (b1 == b2)
b1.datum := 3
msgbox % "b1.datum := 3`n...`nb1 datum: " b1.datum "`nb2 datum: " b2.datum ; is 3 also
msgbox % "b1.datum is b2.datum ? " (b1.datum == b2.datum)
return
borg(){
static borg
If !borg
borg := Object("__Set", "Borg_Set"
, "__Get", "Borg_Get")
return object(1, borg, "base", borg)
}
Borg_Get(brg, name)
{
Return brg[1, name]
}
Borg_Set(brg, name, val)
{
brg[1, name] := val
Return val
}
BASIC
FreeBASIC
REM Sacado del forum de FreeBASIC (https://www.freebasic.net/forum/viewtopic.php?t=20432)
Type singleton
Public :
Declare Static Function crearInstancia() As singleton Ptr
Declare Destructor ()
Dim i As Integer
Private :
Declare Constructor()
Declare Constructor(Byref rhs As singleton)
Declare Static Function instancia(Byval crear As Integer) As singleton Ptr
End Type
Static Function singleton.crearInstancia() As singleton Ptr
Return singleton.instancia(1)
End Function
Static Function singleton.instancia(Byval crear As Integer) As singleton Ptr
Static ref As singleton Ptr = 0
Function = 0
If crear = 0 Then
ref = 0
Elseif ref = 0 Then
ref = New singleton
Function = ref
End If
End Function
Constructor singleton ()
End Constructor
Destructor singleton()
singleton.instancia(0)
End Destructor
'-----------------------------------------------------------------------------
Dim As singleton Ptr ps1 = singleton.crearinstancia()
ps1->i = 1234
Print ps1, ps1->i
Dim As singleton Ptr ps2 = singleton.crearinstancia()
Print ps2
Delete ps1
Dim As singleton Ptr ps3 = singleton.crearinstancia()
Print ps3, ps3->i
Delete ps3
Sleep
- Output:
2038352 1234 0 2038352 0
OxygenBasic
Class Singleton
static sys inst 'private
int instantiated() { return inst }
void constructor(){ if not inst then inst=@this }
'all other methods start with @this=inst
end class
'if not singleton.instantiated
new Singleton MySingleton
'endif
PureBasic
Native version
Thread safe version.
Global SingletonSemaphore=CreateSemaphore(1)
Interface OO_Interface ; Interface for any value of this type
Get.i()
Set(Value.i)
Destroy()
EndInterface
Structure OO_Structure ; The *VTable structure
Get.i
Set.i
Destroy.i
EndStructure
Structure OO_Var
*VirtualTable.OO_Structure
Value.i
EndStructure
Procedure OO_Get(*Self.OO_Var)
ProcedureReturn *Self\Value
EndProcedure
Procedure OO_Set(*Self.OO_Var, n)
*Self\Value = n
EndProcedure
Procedure CreateSingleton()
If TrySemaphore(SingletonSemaphore)
*p.OO_Var = AllocateMemory(SizeOf(OO_Var))
If *p
*p\VirtualTable = ?VTable
EndIf
EndIf
ProcedureReturn *p
EndProcedure
Procedure OO_Destroy(*Self.OO_Var)
FreeMemory(*Self)
SignalSemaphore(SingletonSemaphore)
EndProcedure
DataSection
VTable:
Data.i @OO_Get()
Data.i @OO_Set()
Data.i @OO_Destroy()
EndDataSection
Simple OOP extension
Using the open-source precompiler SimpleOOP.
Singleton Class Demo
BeginPrivate
Name$
X.i
EndPrivate
Public Method Init(Name$)
This\Name$ = Name$
EndMethod
Public Method GetX()
MethodReturn This\X
EndMethod
Public Method SetX(n)
This\X = n
EndMethod
Public Method Hello()
MessageRequester("Hello!", "I'm "+This\Name$)
EndMethod
EndClass
C
Since C doesn't really support classes anyhow, there's not much to do. If you want somethin akin to a singleton, what you do is first declare the interface functions in a header (.h) file.
#ifndef SILLY_H
#define SILLY_H
extern void JumpOverTheDog( int numberOfTimes);
extern int PlayFetchWithDog( float weightOfStick);
#endif
Then in a separate C source (.c) file, define your structures, variables and functions.
...
#include "silly.h"
struct sDog {
float max_stick_weight;
int isTired;
int isAnnoyed;
};
static struct sDog lazyDog = { 4.0, 0,0 };
/* define functions used by the functions in header as static */
static int RunToStick( )
{...
}
/* define functions declared in the header file. */
void JumpOverTheDog(int numberOfTimes)
{ ...
lazyDog.isAnnoyed = TRUE;
}
int PlayFetchWithDog( float weightOfStick )
{ ...
if(weightOfStick < lazyDog.max_stick_weight){...
}
Code using the singleton includes the header and cannot create a struct sDog as the definition is only in the C source (or other header privately included by the silly.c source). Only the functions declared in the header may be used externally.
...
#include "silly.h"
...
/* code using the dog methods */
JumpOverTheDog( 4);
retrieved = PlayFetchWithDog( 3.1);
...
C#
First attempt at thread-safety using locking.
Performance suffers because the lock is acquired every time Instance is accessed.
This implementation is extremely slow and should not be used (but is seen often).
public sealed class Singleton1 //Lazy: Yes ||| Thread-safe: Yes ||| Uses locking: Yes
{
private static Singleton1 instance;
private static readonly object lockObj = new object();
public static Singleton1 Instance {
get {
lock(lockObj) {
if (instance == null) {
instance = new Singleton1();
}
}
return instance;
}
}
}
Fixes excessive locking by double-checking for null.
Still uses locking and implementation is ugly and verbose.
public sealed class Singleton2 //Lazy: Yes ||| Thread-safe: Yes ||| Uses locking: Yes, but only once
{
private static Singleton2 instance;
private static readonly object lockObj = new object();
public static Singleton2 Instance {
get {
if (instance == null) {
lock(lockObj) {
if (instance == null) {
instance = new Singleton2();
}
}
}
return instance;
}
}
}
Really simple implementation without locking.
It still is not completely lazy. If there are other static members, accessing any of those will still cause initialization.
public sealed class Singleton3 //Lazy: Yes, but not completely ||| Thread-safe: Yes ||| Uses locking: No
{
private static Singleton3 Instance { get; } = new Singleton3();
static Singleton3() { }
}
Truly lazy by using an inner class.
This version is completely lazy but the code looks more complicated than it needs to be.
public sealed class Singleton4 //Lazy: Yes ||| Thread-safe: Yes ||| Uses locking: No
{
public static Singleton4 Instance => SingletonHolder.instance;
private class SingletonHolder
{
static SingletonHolder() { }
internal static readonly Singleton4 instance = new Singleton4();
}
}
Using Lazy<T>
C# has a dedicated type for lazy initialization: Lazy<T>.
It makes implementing a Singleton really easy. Recommended.
public sealed class Singleton5 //Lazy: Yes ||| Thread-safe: Yes ||| Uses locking: No
{
private static readonly Lazy<Singleton5> lazy = new Lazy<Singleton5>(() => new Singleton5());
public static Singleton5 Instance => lazy.Value;
}
C++
A generic singleton template class (implemented via the "Curiously Recurring Template Pattern"[1]). Warning: if using a version of C++ prior to C++11, a mutex (or similar) is required to access static variables within a multi-threaded program.
#include <stdexcept>
template <typename Self>
class singleton
{
protected:
static Self*
sentry;
public:
static Self&
instance()
{
return *sentry;
}
singleton()
{
if(sentry)
throw std::logic_error("Error: attempt to instantiate a singleton over a pre-existing one!");
sentry = (Self*)this;
}
virtual ~singleton()
{
if(sentry == this)
sentry = 0;
}
};
template <typename Self>
Self*
singleton<Self>::sentry = 0;
/*
Example usage:
*/
#include <iostream>
#include <string>
using namespace
std;
class controller : public singleton<controller>
{
public:
controller(string const& name)
: name(name)
{
trace("begin");
}
~controller()
{
trace("end");
}
void
work()
{
trace("doing stuff");
}
void
trace(string const& message)
{
cout << name << ": " << message << endl;
}
string
name;
};
int
main()
{
controller*
first = new controller("first");
controller::instance().work();
delete first;
/*
No problem, our first controller no longer exists...
*/
controller
second("second");
controller::instance().work();
try
{
/*
Never happens...
*/
controller
goner("goner");
controller::instance().work();
}
catch(exception const& error)
{
cout << error.what() << endl;
}
controller::instance().work();
/*
Never happens (and depending on your system this may or may not print a helpful message!)
*/
controller
goner("goner");
controller::instance().work();
}
Caché ObjectScript
In Caché, each job runs in a self-contained execution environment (i.e. a separate process instead of a thread). However, it is possible for each process to share data through multidimensional storage (global variables). This is because when the Caché virtual machine starts, it allocates a single, large chunk of shared memory to allow all Caché processes to access this data simultaneously. However, it is the responsibility of the application developer to ensure read and write access to objects is properly co-ordinated (or 'synchronized') between processes to prevent concurrency problems. Also, Caché defines any global variable whose name starts with 'CacheTemp' as being temporary, which means changes are not usually written to disk and are instead maintained within the in-memory buffer pool.
/// The <CLASS>Singleton</CLASS> class represents a global singleton object that can
/// be instantiated by multiple processes. The 'Get' class method is used to obtain
/// an in-memory object reference and the 'Set' method is used to save any changes to
/// state. See below for an example.
///
/// <EXAMPLE>
/// Set one=##class(Singleton).Get(,.sc)
/// Set one.GlobalProperty="Some Value"
/// Set sc=one.Set()
/// </EXAMPLE>
///
/// This class can also be extended.
Class User.Singleton Extends %SerialObject
{
Property GlobalProperty As %String;
/// Refer to <LINK href=/AboutConcurrency.html>About Concurrency</LINK> for more details
/// on the optional <var>pConcurrency</var> argument.
ClassMethod Get(pConcurrency As %Integer = -1, Output pStatus As %Status = {$$$OK}) As Singleton [ Final ]
{
// check if singleton object already instantiated
Set oRef = ""
For {
Set oRef = $ZObjNext(oRef) If oRef = "" Quit
If oRef.%ClassName(1) = ..%ClassName(1) Quit
}
If $IsObject(oRef) Quit oRef
// determine what lock needs to be applied
If '$IsValidNum(pConcurrency, 0, -1, 4) {
Set pStatus = $$$ERROR($$$LockTypeInvalid, pConcurrency)
Quit $$$NULLOREF
}
If pConcurrency = -1 Set pConcurrency = $Xecute("Quit "_..#DEFAULTCONCURRENCY)
// acquire lock for global singleton object
Set lockTO = $ZUtil(115,4), lockOK = 1
If pConcurrency<4, pConcurrency {
Lock +^CacheTempUser("Singleton", ..%ClassName(1))#"S":lockTO Set lockOK = $Test
} ElseIf pConcurrency = 4 {
Lock +^CacheTempUser("Singleton", ..%ClassName(1)):lockTO Set lockOK = $Test
}
If 'lockOK {
If pConcurrency = 4 {
Set pStatus = $$$ERROR($$$LockFailedToAcquireExclusive, ..%ClassName(1))
} Else {
Set pStatus = $$$ERROR($$$LockFailedToAcquireRead, ..%ClassName(1))
}
Quit $$$NULLOREF
}
// retrieve global singleton object and deserialise
Set oId = $Get(^CacheTempUser("Singleton", ..%ClassName(1)))
Set oRef = ..%Open(oId) //,, .pStatus)
If '$IsObject(oRef) Set pStatus = $$$ERROR($$$GeneralError, "Failed to load singleton object.")
// release temporary lock
If (pConcurrency = 1) || (pConcurrency = 2) {
Lock -^CacheTempUser("Singleton", ..%ClassName(1))#"S"
}
// singleton object failed to load
If $$$ISERR(pStatus) {
// release retained lock
If pConcurrency = 3 {
Lock -^CacheTempUser("Singleton", ..%ClassName(1))#"S"
}
If pConcurrency = 4 {
Lock -^CacheTempUser("Singleton", ..%ClassName(1))
}
Quit $$$NULLOREF
}
// store concurrency state and return in-memory object reference
Set oRef.Concurrency = pConcurrency
Quit oRef
}
Method Set() As %Status [ Final ]
{
// check for version change
Set oId0 = $Get(^CacheTempUser("Singleton", ..%ClassName(1)))
Set oRef0 = ..%Open(oId0) //,, .sc)
If '$IsObject(oRef0) Quit $$$ERROR($$$GeneralError, "Failed to load singleton object.")
If oRef0.Version = ..Version {
Set ..Version = ..Version + 1
} Else {
Quit $$$ERROR($$$ConcurrencyVersionMismatch, ..%ClassName(1))
}
// serialise local singleton object and check status code
Set sc = ..%GetSwizzleObject(,.oId) If $$$ISERR(sc) Quit sc
// acquire exclusive lock on global singleton object
Set lockTO = $ZUtil(115,4)
Lock +^CacheTempUser("Singleton", ..%ClassName(1)):lockTO
If '$Test Quit $$$ERROR($$$LockFailedToAcquireExclusive, ..%ClassName(1))
// update global singleton object and release lock
Set ^CacheTempUser("Singleton", ..%ClassName(1)) = oId
Lock -^CacheTempUser("Singleton", ..%ClassName(1))
Quit $$$OK
}
Method %OnNew() As %Status [ Final, Internal ]
{
// do not allow constructor method to be called
Quit $$$ERROR($$$GeneralError, "Can't instantiate directly.")
}
Method %OnConstructClone() As %Status [ Final, Internal ]
{
// do not allow singleton object to be cloned
Quit $$$ERROR($$$GeneralError, "Can't clone instance.")
}
Method %OnClose() As %Status [ Final, Internal ]
{
// reference count for singleton object is now zero, so
// release lock on global singleton object, if applicable
If ..Concurrency = 3 Lock -^CacheTempUser("Singleton", ..%ClassName(1))#"S"
If ..Concurrency = 4 Lock -^CacheTempUser("Singleton", ..%ClassName(1))
Quit $$$OK
}
Property Concurrency As %Integer [ Final, Private, Transient ];
Property Version As %Integer [ Final, Private ];
}
- Examples:
USER>Set one=##class(Singleton).Get() USER>Set one.GlobalProperty="Some Value" USER>Set sc=one.Set()
Common Lisp
Since Common Lisp uses generic functions for dispatch, creating a class is not necessary. If the superclasses of the singleton are not important, the simplest thing to do is to use a particular symbol; methods use eql specializers to be applicable to only that object.
For a simple example, the following program constructs English sentences without worrying about extra space occurring at points where no text (the-empty-phrase
, our singleton) is inserted.
(defgeneric concat (a b)
(:documentation "Concatenate two phrases."))
(defclass nonempty-phrase ()
((text :initarg :text :reader text)))
(defmethod concat ((a nonempty-phrase) (b nonempty-phrase))
(make-instance 'nonempty-phrase :text (concatenate 'string (text a) " " (text b))))
(defmethod concat ((a (eql 'the-empty-phrase)) b)
b)
(defmethod concat (a (b (eql 'the-empty-phrase)))
a)
(defun example ()
(let ((before (make-instance 'nonempty-phrase :text "Jack"))
(mid (make-instance 'nonempty-phrase :text "went"))
(after (make-instance 'nonempty-phrase :text "to fetch a pail of water")))
(dolist (p (list 'the-empty-phrase
(make-instance 'nonempty-phrase :text "and Jill")))
(dolist (q (list 'the-empty-phrase
(make-instance 'nonempty-phrase :text "up the hill")))
(write-line (text (reduce #'concat (list before p mid q after))))))))
Thread safety is irrelevant since the singleton is created at load time, not first access.
D
module singleton ;
import std.stdio ;
import std.thread ;
import std.random ;
import std.c.time ;
class Dealer {
private static Dealer me ;
static Dealer Instance() {
writefln(" Calling Dealer... ") ;
if(me is null) // Double Checked Lock
synchronized // this part of code can only be executed by one thread a time
if(me is null)
me = new Dealer ;
return me ;
}
private static string[] str = ["(1)Enjoy", "(2)Rosetta", "(3)Code"] ;
private int state ;
private this() {
for(int i = 0 ; i < 3 ; i++) {
writefln("...calling Dealer... ") ;
msleep(rand() & 2047) ;
}
writefln(">>Dealer is called to come in!") ;
state = str.length - 1 ;
}
Dealer nextState() {
synchronized(this) // accessed to Object _this_ is locked ... is it necessary ???
state = (state + 1) % str.length ;
return this ;
}
string toString() { return str[state] ; }
}
class Coder : Thread {
private string name_ ;
Coder hasName(string name) { name_ = name ; return this ; }
override int run() {
msleep(rand() & 1023) ;
writefln(">>%s come in.", name_) ;
Dealer single = Dealer.Instance ;
msleep(rand() & 1023) ;
for(int i = 0 ; i < 3 ; i++) {
writefln("%9s got %-s", name_, single.nextState) ;
msleep(rand() & 1023) ;
}
return 0 ;
}
}
void main() {
Coder x = new Coder ;
Coder y = new Coder ;
Coder z = new Coder ;
x.hasName("Peter").start() ;
y.hasName("Paul").start() ;
z.hasName("Mary").start() ;
x.wait ; y.wait ; z.wait ;
}
- Output:
>>Mary come in. Calling Dealer... ...calling Dealer... >>Peter come in. Calling Dealer... >>Paul come in. Calling Dealer... ...calling Dealer... ...calling Dealer... >>Dealer is called to come in! Mary got (1)Enjoy Peter got (2)Rosetta Mary got (3)Code Paul got (1)Enjoy Peter got (2)Rosetta Paul got (3)Code Paul got (1)Enjoy Mary got (2)Rosetta Peter got (3)Code
Delphi and Pascal
Detailed explanation here. (Delphi started out as an object-oriented version of Pascal.)
unit Singleton;
interface
type
TSingleton = class
private
//Private fields and methods here...
class var _instance: TSingleton;
protected
//Other protected methods here...
public
//Global point of access to the unique instance
class function Create: TSingleton;
destructor Destroy; override;
//Other public methods and properties here...
end;
implementation
{ TSingleton }
class function TSingleton.Create: TSingleton;
begin
if (_instance = nil) then
_instance:= inherited Create as Self;
result:= _instance;
end;
destructor TSingleton.Destroy;
begin
_instance:= nil;
inherited;
end;
end.
E
Since E uses closure-style objects rather than classes, a singleton is simply an object which is defined at the top level of the program, not inside any method. There are no thread-safety issues since the singleton, like every other object, belongs to some particular vat (but can be remotely invoked from other vats).
def aSingleton {
# ...
}
Ecstasy
The static
keyword in a class declaration will compile that class as a singleton. It is legal to define const
(i.e. immutable) and service
classes as singletons. Modules, packages, and enumeration values are always singleton classes. It is not legal to define normal class
classes as singletons, because normal classes are mutable, and Ecstasy does not allow shared mutable state.
The name of the class is used to specify that singleton instance:
module test {
static service Singleton {
private Int counter;
String fooHasBeenCalled() {
return $"{++counter} times";
}
}
void run() {
@Inject Console console;
for (Int i : 1..5) {
console.print($"{Singleton.fooHasBeenCalled()=}");
}
}
}
- Output:
x$ xec test Singleton.fooHasBeenCalled()=1 times Singleton.fooHasBeenCalled()=2 times Singleton.fooHasBeenCalled()=3 times Singleton.fooHasBeenCalled()=4 times Singleton.fooHasBeenCalled()=5 times
Eiffel
Non-Thread Safe
Taken from this dated site
Implementation:
class
SINGLETON
create {SINGLETON_ACCESS}
default_create
feature
-- singleton features go here
end
frozen class
SINGLETON_ACCESS
feature
singleton: SINGLETON
once ("PROCESS")
create Result
ensure
Result /= Void
end
end
Usage:
s: SINGLETON -- declaration somewhere
s := (create{SINGLETON_ACCESS}).singleton -- in some routine
Elena
Stateless singleton
singleton Singleton
{
// ...
}
Normal singleton
class Singleton
{
object theField;
// ...
}
static singleton = new Singleton();
EMal
type Singleton
model
text greeting
fun speak = void by block do writeLine(me.greeting + " I'm a singleton") end
end
Singleton instance
fun getInstance = Singleton by block
if instance == null do instance = Singleton() end
return instance
end
type SomeOtherType
Singleton s1 = Singleton.getInstance()
s1.greeting = "Hello"
Singleton s2 = Singleton.getInstance()
s2.greeting.append(", World!")
writeLine(s1 + " and " + s2 + " are the same object: " + (s1 == s2) + ", s2: " + s2.greeting)
s1.speak() # call instance method
- Output:
§(0x02bf8098) and §(0x02bf8098) are the same object: ⊤, s2: Hello, World! Hello, World! I'm a singleton
Epoxy
fn Singleton()
if this.self then return this.self cls
var new: {}
iter k,v as this._props do
new[k]:v
cls
this.self:new
return new
cls
Singleton._props: {
name: "Singleton",
fn setName(self,new)
self.name:new
cls,
}
var MySingleton: Singleton()
log(MySingleton == Singleton()) --true
log(MySingleton.name) --Singleton
var NewSingleton: Singleton()
NewSingleton>>setName("Test")
log(MySingleton.name) --Test
- Output:
true Singleton Test
Erlang
Erlang is not object-oriented, so there is no such thing as a singleton class. The singleton is something of an anti-pattern in Erlang, so if you are tempted to do this, there is probably a better architecture. If you do want something akin to a singleton, you start and register a process that maintains its state in a message loop and provides its state to anyone that wants it or needs to change it. Since this is done with message passing, it's safe for concurrent use.
-module(singleton).
-export([get/0, set/1, start/0]).
-export([loop/1]).
% spec singleton:get() -> {ok, Value::any()} | not_set
get() ->
?MODULE ! {get, self()},
receive
{ok, not_set} -> not_set;
Answer -> Answer
end.
% spec singleton:set(Value::any()) -> ok
set(Value) ->
?MODULE ! {set, self(), Value},
receive
ok -> ok
end.
start() ->
register(?MODULE, spawn(?MODULE, loop, [not_set])).
loop(Value) ->
receive
{get, From} ->
From ! {ok, Value},
loop(Value);
{set, From, NewValue} ->
From ! ok,
loop(NewValue)
end.
Here is an example of how to use it (from the shell). It assumes singleton:start/0 was already called from the supervisor tree (as would be typical if you were using something like this).
1> singleton:get().
not_set
2> singleton:set(apple).
ok
3> singleton:get().
{ok,apple}
4> singleton:set("Pear").
ok
5> singleton:get().
{ok,"Pear"}
6> singleton:set(42).
ok
7> singleton:get().
{ok,42}
Factor
USING: classes.singleton kernel io prettyprint ;
IN: singleton-demo
SINGLETON: bar
GENERIC: foo ( obj -- )
M: bar foo drop "Hello!" print ;
( scratchpad ) bar foo Hello!
Forth
Works with any ANS Forth
Needs the FMS2VT Forth extension located here: https://github.com/DouglasBHoffman/FMS2/tree/master/FMS2VT
include FMS2VT.f
\ A singleton is created by using normal Forth data
\ allocation words such as value or variable as instance variables.
\ Any number of instances of a singleton class may be
\ instantiated but messages will all operate on the same shared data
\ so it is the same as if only one object has been created.
\ The data name space will remain private to the class.
:class singleton
0 value a
0 value b
:m printa a . ;m
:m printb b . ;m
:m add-a ( n -- ) a + to a ;m
:m add-b ( n -- ) b + to b ;m
;class
singleton s1
singleton s2
singleton s3
4 s1 add-a
9 s2 add-b
s3 printa \ => 4
s3 printb \ => 9
s1 printb \ => 9
s2 printa \ => 4
Go
sync.Once
From the Go standard library, sync.Once provides a way to ensure that some "step," effectively an initialization step, is performed no more than once even if it might be attempted from multiple concurrent goroutines. This capability might be considered similar to some mechanism ensuring that singleton constructor code is only run once.
package main
import (
"log"
"math/rand"
"sync"
"time"
)
var (
instance string
once sync.Once // initialize instance with once.Do
)
func claim(color string, w *sync.WaitGroup) {
time.Sleep(time.Duration(rand.Intn(1e8))) // hesitate up to .1 sec
log.Println("trying to claim", color)
once.Do(func() { instance = color })
log.Printf("tried %s. instance: %s", color, instance)
w.Done()
}
func main() {
rand.Seed(time.Now().Unix())
var w sync.WaitGroup
w.Add(2)
go claim("red", &w) // these two attempts run concurrently
go claim("blue", &w)
w.Wait()
log.Println("after trying both, instance =", instance)
}
- Output:
2016/07/01 20:36:02 trying to claim red 2016/07/01 20:36:02 tried red. instance: red 2016/07/01 20:36:02 trying to claim blue 2016/07/01 20:36:02 tried blue. instance: red 2016/07/01 20:36:02 after trying both, instance = red
Packages as singletons
Go packages are singletons, in a way. Go does not use the word "class," and while Go structs might seem most like classes of other languages, Go packages are also like classes in that they represent an organization of declarations, including data and functions. All declarations in a package form a single package block. This block is delimited syntactically, has an associated identifier, and its members are accessed by this package identifier. This is much like classes in other languages.
Because packages cannot be imported multiple times, data declared at package level will only ever have a single instance, and the package as a whole serves as a singleton.
package singlep
// package level data declarations serve as singleton instance variables
var X, Y int
// package level initialization can serve as constructor code
func init() {
X, Y = 2, 3
}
// package level functions serve as methods for a package-as-a-singleton
func F() int {
return Y - X
}
Example program using the package:
package main
import (
"fmt"
"singlep"
)
func main() {
// dot selector syntax references package variables and functions
fmt.Println(singlep.X, singlep.Y)
fmt.Println(singlep.F())
}
- Output:
2 3 1
Package data initialization with sync.Once
This example combines the two previous concepts and also shows some additional concepts. It has packages imported with a "diamond" dependency. While both red
and blue
import single
, only a single variable color
will exist in memory. The init()
mechanism shown above actually runs before main()
. In contrast, the sync.Once
mechanism can serve as constructor code after main()
begins.
package single
import (
"log"
"sync"
)
var (
color string
once sync.Once
)
func Color() string {
if color == "" {
panic("color not initialized")
}
return color
}
func SetColor(c string) {
log.Println("color initialization")
once.Do(func() { color = c })
log.Println("color initialized to", color)
}
package red
import (
"log"
"single"
)
func SetColor() {
log.Println("trying to set red")
single.SetColor("red")
}
package blue
import (
"log"
"single"
)
func SetColor() {
log.Println("trying to set blue")
single.SetColor("blue")
}
package main
import (
"log"
"math/rand"
"time"
"blue"
"red"
"single"
)
func main() {
rand.Seed(time.Now().Unix())
switch rand.Intn(3) {
case 1:
red.SetColor()
blue.SetColor()
case 2:
blue.SetColor()
red.SetColor()
}
log.Println(single.Color())
}
- Output:
2016/07/01 20:52:18 trying to set red 2016/07/01 20:52:18 color initialization 2016/07/01 20:52:18 color initialized to red 2016/07/01 20:52:18 trying to set blue 2016/07/01 20:52:18 color initialization 2016/07/01 20:52:18 color initialized to red 2016/07/01 20:52:18 red
Groovy
@Singleton
class SingletonClass {
def invokeMe() {
println 'invoking method of a singleton class'
}
static void main(def args) {
SingletonClass.instance.invokeMe()
}
}
- Output:
invoking method of a singleton class
Icon and Unicon
Icon is not object oriented, but Unicon supports O-O programming.
class Singleton
method print()
write("Hi there.")
end
initially
write("In constructor!")
Singleton := create |self
end
procedure main()
Singleton().print()
Singleton().print()
end
This Unicon example uses a number of Icon features.
- The class descriptor Singleton is a first-class global object.
- The create keyword yields a co-routine which can be activated like a function call.
- The monadic operator | repeatedly yields the iteration of it's argument - in this case, it yields the object created (self).
- The initializer of each object actually replaces the global object Singleton with a coroutine that returns ... the first object created. Therefore there is no further access to the true Singleton constructor; future attempts to create the object instead just activates the co-routine.
NOTE: this could be subverted by capturing a reference to Singleton prior to the first object construction.
Io
Io does not have globals. But it is easy to make singleton objects:
Singleton := Object clone
Singleton clone = Singleton
J
In J, all classes are singletons though their objects are not. (Class names may be used in any context where object references may be used, and object references can be used in almost every context where a class name may be used.)
Singletons should not have a constructor so any attempt to construct an instance of a singleton (dyadic conew
) would fail. Other than that, singletons are defined like any other class in J.
Java
Thread-safe
wp:Double-checked locking; only use with Java 1.5+
class Singleton
{
private static Singleton myInstance;
public static Singleton getInstance()
{
if (myInstance == null)
{
synchronized(Singleton.class)
{
if (myInstance == null)
{
myInstance = new Singleton();
}
}
}
return myInstance;
}
protected Singleton()
{
// Constructor code goes here.
}
// Any other methods
}
Thread-Safe Lazy-Loaded
This is the wp:Initialization-on-demand holder idiom.
public class Singleton {
private Singleton() {
// Constructor code goes here.
}
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}
Thread-Safe Using Enum
Enums in Java are fully-fledged classes with specific instances, and are an idiomatic way to create singletons.
public enum Singleton {
INSTANCE;
// Fields, constructors and methods...
private int value;
Singleton() {
value = 0;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
Non-Thread-Safe
class Singleton
{
private static Singleton myInstance;
public static Singleton getInstance()
{
if (myInstance == null)
{
myInstance = new Singleton();
}
return myInstance;
}
protected Singleton()
{
// Constructor code goes here.
}
// Any other methods
}
JavaScript
function Singleton() {
if(Singleton._instance) return Singleton._instance;
this.set("");
Singleton._instance = this;
}
Singleton.prototype.set = function(msg) { this.msg = msg; }
Singleton.prototype.append = function(msg) { this.msg += msg; }
Singleton.prototype.get = function() { return this.msg; }
var a = new Singleton();
var b = new Singleton();
var c = new Singleton();
a.set("Hello");
b.append(" World");
c.append("!!!");
document.write( (new Singleton()).get() );
Julia
Julia allows singletons as type declarations without further specifiers. There can be only one instance of such a type, and if more than one variable is bound to such a type they are actually all bound to the same instance in memory:
struct IAmaSingleton end
x = IAmaSingleton()
y = IAmaSingleton()
println("x == y is $(x == y) and x === y is $(x === y).")
Kotlin
Kotlin has built-in support for singletons via object declarations. To refer to the singleton, we simply use its name which can be any valid identifier other than a keyword:
// version 1.1.2
object Singleton {
fun speak() = println("I am a singleton")
}
fun main(args: Array<String>) {
Singleton.speak()
}
- Output:
I am a singleton
M2000 Interpreter
Module CheckSingleton {
\\ singleton
\\ pointers and static groups are the same object because
\\ each one has a pointer to same state (a tuple)
\\ but from outside we do the miracle to have a static group to act as a pointer
\\ We need a lambda function to hold the pointer to Singleton as closure
Global One=lambda M=pointer() (aValue=0)-> {
If M is type null then
\\ one time happen
Group Singleton {
Type:One
Private:
state=(aValue,)
Public:
module Add (x) {
.state+=x
}
Set {Drop}
Value {
=.state#val(0)
}
}
M->group(Singleton)
end if
\\ return M which is a pointer
=M
}
K=One(100)
Print Eval(K)=100
M=One()
Print Eval(M)=100
Print K is M = true
Print K is type One = true
K=>add 500
Print eval(K)=600
\\ copy K to Z (no pointer to Z, Z is named group)
Z=Group(K)
Print eval(z)=600, z=600
Z.add 1000
Print Z=1600, Eval(M)=1600, Eval(K)=1600
\\ push a copy of Z, but state is pointer so we get a copy of a pointer
Push Group(Z)
Read beta
Beta.add 1000
Print Z=2600, Eval(M)=2600, Eval(K)=2600
\\ convert pointer to group (a copy of group)
group delta=One()
delta.add 1000
Print Z=3600, beta=3600, delta=3600, Eval(M)=3600, Eval(K)=3600
\\ M and K are pointers to groups
M=>add 400
Print Z=4000, beta=4000, delta=4000, Eval(M)=4000, Eval(K)=4000
}
CheckSingleton
Lasso
Lasso supports singletons on two levels.
Server wide singleton
// Define the thread if it doesn't exist
// New definition supersede any current threads.
not ::serverwide_singleton->istype
? define serverwide_singleton => thread {
data public switch = 'x'
}
local(
a = serverwide_singleton,
b = serverwide_singleton,
)
#a->switch = 'a'
#b->switch = 'b'
#a->switch // b
Thread level singleton
// Define thread level singleton
define singleton => type {
data public switch = 'x'
public oncreate => var(.type)->isa(.type) ? var(.type) | var(.type) := self
}
local(
a = singleton,
b = singleton,
)
#a->switch = 'a'
#b->switch = 'b'
#a->switch // b
Latitude
Latitude objects are prototypes, so any new object can be treated as a singleton by simply not cloning it. For added security, one can always override clone
to make it clear that the object should not be cloned, but this is generally overkill.
Singleton ::= Object clone tap {
self id := 0.
self newID := {
self id := self id + 1.
}.
self clone := {
err ArgError clone tap { self message := "Singleton object!". } throw.
}.
}.
println: Singleton newID. ; 1
println: Singleton newID. ; 2
println: Singleton newID. ; 3
Lingo
In Lingo a Singleton class can be implemented like this:
-- parent script "SingletonDemo"
property _instance
property _someProperty
----------------------------------------
-- @constructor
----------------------------------------
on new (me)
if not voidP(me.script._instance) then return me.script._instance
me.script._instance = me
me._someProperty = 0
return me
end
----------------------------------------
-- sample method
----------------------------------------
on someMethod (me, x)
me._someProperty = me._someProperty + x
return me._someProperty
end
Logtalk
Logtalk supports both classes and prototypes. A prototype is a much simpler solution for defining a singleton object than defining a class with only an instance.
:- object(singleton).
:- public(value/1).
value(Value) :-
state(Value).
:- public(set_value/1).
set_value(Value) :-
retract(state(_)),
assertz(state(Value)).
:- private(state/1).
:- dynamic(state/1).
state(0).
:- end_object.
A simple usage example after compiling and loading the code above:
| ?- singleton::value(Value).
Value = 0
yes
| ?- singleton::(set_value(1), value(Value)).
Value = 1
yes
NetRexx
Uses a static field to avoid synchronization problems and the flawed "double-checked locking" idiom in JVMs. See www.ibm.com/developerworks/java/library/j-dcl/index.html for a detailed explanation.
/* NetRexx */
options replace format comments java crossref symbols binary
import java.util.random
class RCSingleton public
method main(args = String[]) public static
RCSingleton.Testcase.main(args)
return
-- ---------------------------------------------------------------------------
class RCSingleton.Instance public
properties private static
_instance = Instance()
properties private
_refCount = int
_random = Random
method Instance() private
this._refCount = 0
this._random = Random()
return
method getInstance public static returns RCSingleton.Instance
return _instance
method getRandom public returns Random
return _random
method addRef public protect
_refCount = _refCount + 1
return
method release public protect
if _refCount > 0 then
_refCount = _refCount - 1
return
method getRefCount public protect returns int
return _refCount
-- ---------------------------------------------------------------------------
class RCSingleton.Testcase public implements Runnable
properties private
_instance = RCSingleton.Instance
method run public
say threadInfo'|-'
thud = Thread.currentThread
_instance = RCSingleton.Instance.getInstance
thud.yield
_instance.addRef
say threadInfo'|'_instance.getRefCount
thud.yield
do
thud.sleep(_instance.getRandom.nextInt(1000))
catch ex = InterruptedException
ex.printStackTrace
end
_instance.release
say threadInfo'|'_instance.getRefCount
return
method main(args = String[]) public static
threads = [ Thread -
Thread(Testcase()), Thread(Testcase()), Thread(Testcase()), -
Thread(Testcase()), Thread(Testcase()), Thread(Testcase()) ]
say threadInfo'|-'
mn = Testcase()
mn._instance = RCSingleton.Instance.getInstance
say mn.threadInfo'|'mn._instance.getRefCount
mn._instance.addRef
say mn.threadInfo'|'mn._instance.getRefCount
do
loop tr over threads
(Thread tr).start
end tr
Thread.sleep(400)
catch ex = InterruptedException
ex.printStackTrace
end
mn._instance.release
say mn.threadInfo'|'mn._instance.getRefCount
return
method threadInfo public static returns String
trd = Thread.currentThread
tid = trd.getId
hc = trd.hashCode
info = Rexx(trd.getName).left(16, '_')':' -
|| Rexx(Long.toString(tid)).right(10, 0)':' -
|| '@'Rexx(Integer.toHexString(hc)).right(8, 0)
return info
- Output:
main____________:0000000001:@035a8767|- main____________:0000000001:@035a8767|0 main____________:0000000001:@035a8767|1 Thread-1________:0000000010:@22998b08|- Thread-1________:0000000010:@22998b08|2 Thread-2________:0000000011:@7a6d084b|- Thread-2________:0000000011:@7a6d084b|3 Thread-3________:0000000012:@2352544e|- Thread-4________:0000000013:@457471e0|- Thread-5________:0000000014:@7ecec0c5|- Thread-6________:0000000015:@3dac2f9c|- Thread-3________:0000000012:@2352544e|4 Thread-4________:0000000013:@457471e0|5 Thread-5________:0000000014:@7ecec0c5|6 Thread-6________:0000000015:@3dac2f9c|7 Thread-5________:0000000014:@7ecec0c5|6 main____________:0000000001:@035a8767|5 Thread-3________:0000000012:@2352544e|4 Thread-1________:0000000010:@22998b08|3 Thread-6________:0000000015:@3dac2f9c|2 Thread-2________:0000000011:@7a6d084b|1 Thread-4________:0000000013:@457471e0|0
Nim
In the file singleton.nim
we don't export the type, so new objects can't be created:
type Singleton = object # Singleton* would export
foo*: int
var single* = Singleton(foo: 0)
Then in another file we can use the singleton object:
import singleton
single.foo = 12
echo single.foo
Objeck
class Singleton {
@singleton : static : Singleton;
New : private () {
}
function : GetInstance() ~ Singleton {
if(@singleton <> Nil) {
@singleton := Singleton->New();
};
return @singleton;
}
method : public : DoStuff() ~ Nil {
...
}
}
Objective-C
Non-Thread-Safe
(Using Cocoa/OpenStep's NSObject as a base class)
// SomeSingleton.h
@interface SomeSingleton : NSObject
{
// any instance variables
}
+ (SomeSingleton *)sharedInstance;
@end
// SomeSingleton.m
@implementation SomeSingleton
+ (SomeSingleton *) sharedInstance
{
static SomeSingleton *sharedInstance = nil;
if (!sharedInstance) {
sharedInstance = [[SomeSingleton alloc] init];
}
return sharedInstance;
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (unsigned)retainCount
{
return UINT_MAX;
}
- (oneway void)release
{
// prevent release
}
- (id)autorelease
{
return self;
}
@end
Thread-Safe
Same as above except:
+ (SomeSingleton *) sharedInstance
{
static SomeSingleton *sharedInstance = nil;
@synchronized(self) {
if (!sharedInstance) {
sharedInstance = [[SomeSingleton alloc] init];
}
}
return sharedInstance;
}
With GCD
Same as above except:
+ (SomeSingleton *) sharedInstance
{
static SomeSingleton *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[SomeSingleton alloc] init];
});
return sharedInstance;
}
With class methods
It's possible to accomplish the same thing with class methods of some class, rather than instance methods on the instance of a singleton class. Data that needs to be kept as "instance variables" would instead be kept as static
(file-local) global variables. "Initialization" of the singleton object would be done in the +initialize
method, which is guaranteed to be called at most once for every class, the first time the class is messaged. This way, the singleton is also "lazy loaded" as needed.
In other words, here the class object serves as the singleton object. The "singleton class" is the metaclass of the class. The downside of this approach is that the "singleton class" (the metaclass of the class) cannot be made to explicitly inherit from a class of the user's choice, or implement a protocol of the user's choice. Also, there is no way to prevent subclasses of the class from being made, thus effectively creating "multiple instances" of the singleton class. Also, one cannot declare properties on the singleton (the class object).
Oforth
Oforth does not have global variables, class attributes or some kind of shared mutable memory that can be updated by different tasks.
In Oforth, singleton is an anti-pattern because it needs synchronisation in order to be safe between parallel tasks.
If the goal is to keep and update a value in a safe way, a channel can be used.
For instance, this Sequence class creates instances that increment an integer and send it. If a task tries to get the next value before it is incremented, it will wait until the channel is no more empty and holds the new value. This won't work if the value is a mutable value (you will get an exception if you try to send a mutable object into channel). A mutable object can't be shared between tasks. Here we send a new integer each time.
Object Class new: Sequence(channel)
Sequence method: initialize(initialValue)
Channel newSize(1) := channel
@channel send(initialValue) drop ;
Sequence method: nextValue @channel receive dup 1 + @channel send drop ;
Usage :
import: parallel
: testSequence
| s i |
Sequence new(0) ->s
100 loop: i [ #[ s nextValue println ] & ] ;
ooRexx
a = .singleton~new
b = .singleton~new
a~foo = "Rick"
if a~foo \== b~foo then say "A and B are not the same object"
::class singleton
-- initialization method for the class
::method init class
expose singleton
-- mark this as unallocated. We could also just allocate
-- the singleton now, but better practice is probably wait
-- until it is requested
singleton = .nil
-- override the new method. Since this is a guarded
-- method by default, this is thread safe
::method new class
expose singleton
-- first request? Do the real creation now
if singleton == .nil then do
-- forward to the super class. We use this form of
-- FORWARD rather than explicit call ~new:super because
-- this takes care of any arguments passed to NEW as well.
forward class(super) continue
singleton = result
end
return singleton
-- an attribute that can be used to demonstrate this really is
a singleton.
::attribute foo
Oz
Singleton is not a common pattern in Oz programs. It can be implemented by limiting the scope of the class definition such that only the GetInstance
function has access to it.
declare
local
class Singleton
meth init
skip
end
end
L = {NewLock}
Instance
in
fun {GetInstance}
lock L then
if {IsFree Instance} then
Instance = {New Singleton init}
end
Instance
end
end
end
This will work as long as all functors are linked with import
statements. If you use multiple calls to Module.link
instead, you will get multiple instances of the "Singleton".
Perl
package Singleton;
use strict;
use warnings;
my $Instance;
sub new {
my $class = shift;
$Instance ||= bless {}, $class; # initialised once only
}
sub name {
my $self = shift;
$self->{name};
}
sub set_name {
my ($self, $name) = @_;
$self->{name} = $name;
}
package main;
my $s1 = Singleton->new;
$s1->set_name('Bob');
printf "name: %s, ref: %s\n", $s1->name, $s1;
my $s2 = Singleton->new;
printf "name: %s, ref: %s\n", $s2->name, $s2;
Phix
Not really any special handling for singletons in Phix, but you can do something like this, or keep check() private and invoke it internally from a few critical routines. Needs 0.8.1+
-- <separate include file>
object chk = NULL
class singleton
public procedure check()
if chk==NULL then
chk = this
elsif this!=chk then
?9/0
end if
?"ok"
end procedure
end class
global singleton s = new()
--global singleton s2 = new()
-- </separate include file>
s.check()
--s2.check() -- dies
While all classes are technically global in the sense that builtins\structs.e knows all about them, the
implicit associated user defined type is by default private (ie w/o "global" in front of the class def).
The above separate file prohibits the use of (other) singleton s = new()
everywhere, however
class s = new("singleton")
could still be used anywhere, and that way get duplicates.
One obvious alternative (of no special merit imo) might be to replace that global singleton s with:
global function get_singleton()
if chk==NULL then
chk = new("singleton")
end if
return chk
end function
Technically, builtins/struct.e looks like it could easily be modified to support something very similar to the Python Borg pattern, by appropriately sharing cdx/tid in new(). However it would be even better to share the whole delete_routine()'d res, and that would probably be best achieved by setting a new flag, say S_SINGLETON or S_STATIC, alongside and triggered via similar syntax to S_ABSTRACT/S_NULLABLE. Maybe.
PHP
class Singleton {
protected static $instance = null;
public $test_var;
private function __construct(){
//Any constructor code
}
public static function getInstance(){
if (is_null(self::$instance)){
self::$instance = new self();
}
return self::$instance;
}
}
$foo = Singleton::getInstance();
$foo->test_var = 'One';
$bar = Singleton::getInstance();
echo $bar->test_var; //Prints 'One'
$fail = new Singleton(); //Fatal error
PicoLisp
As there is no physical difference between classes and objects, we can use the class symbol itself.
(class +Singleton)
(dm message1> ()
(prinl "This is method 1 on " This) )
(dm message2> ()
(prinl "This is method 2 on " This) )
- Output:
: (message1> '+Singleton) This is method 1 on +Singleton -> +Singleton : (message2> '+Singleton) This is method 2 on +Singleton -> +Singleton
Python
per Borg Design
In Python we use the Borg pattern to share state between instances rather than concentrate on identity.
Every instance of the Borg class will share the same state:
>>> class Borg(object):
__state = {}
def __init__(self):
self.__dict__ = self.__state
# Any other class names/methods
>>> b1 = Borg()
>>> b2 = Borg()
>>> b1 is b2
False
>>> b1.datum = range(5)
>>> b1.datum
[0, 1, 2, 3, 4]
>>> b2.datum
[0, 1, 2, 3, 4]
>>> b1.datum is b2.datum
True
>>> # For any datum!
per MetaClass/AbstractBaseClass
An approximation of the singleton can be made using only class attributes to store data instead of the instance attributes, providing at least one abstract instance method (class can not be instantiated then) and making the rest of the methods being class methods. E.g.
import abc
class Singleton(object):
"""
Singleton class implementation
"""
__metaclass__ = abc.ABCMeta
state = 1 #class attribute to be used as the singleton's attribute
@abc.abstractmethod
def __init__(self):
pass #this prevents instantiation!
@classmethod
def printSelf(cls):
print cls.state #prints out the value of the singleton's state
#demonstration
if __name__ == "__main__":
try:
a = Singleton() #instantiation will fail!
except TypeError as err:
print err
Singleton.printSelf()
print Singleton.state
Singleton.state = 2
Singleton.printSelf()
print Singleton.state
When executed this code should print out the following:
Can't instantiate abstract class Singleton with abstract methods __init__
1
1
2
2
So, instantiation is not possible. Only a single object is available, and it behaves as a singleton.
per MetaClass
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class Logger(object):
__metaclass__ = Singleton
or in Python3
class Logger(metaclass=Singleton):
pass
Racket
Singletons are not very useful in Racket, because functions that use module state are more straightforward. However, classes are first class values, and therefore they follow the same rules as all other bindings. For example, a class can be made and instantiated but not provided to client files:
#lang racket
(provide instance)
(define singleton%
(class object%
(super-new)))
(define instance (new singleton%))
Or better, not name the class at all:
#lang racket
(provide instance)
(define instance
(new (class object%
(define/public (foo) 123)
(super-new))))
Raku
(formerly Perl 6)
class Singleton {
# We create a lexical variable in the class block that holds our single instance.
my Singleton $instance = Singleton.bless; # You can add initialization arguments here.
method new {!!!} # Singleton.new dies.
method instance { $instance; }
}
Ruby
require 'singleton'
class MySingleton
include Singleton
# constructor and/or methods go here
end
a = MySingleton.instance # instance is only created the first time it is requested
b = MySingleton.instance
puts a.equal?(b) # outputs "true"
Scala
The object construct in Scala is a singleton.
object Singleton {
// any code here gets executed as if in a constructor
}
Sidef
class Singleton(name) {
static instance;
method new(name) {
instance := Singleton.bless(Hash(:name => name));
}
method new {
Singleton.new(nil);
}
}
var s1 = Singleton('foo');
say s1.name; #=> 'foo'
say s1.object_id; #=> '30424504'
var s2 = Singleton();
say s2.name; #=> 'foo'
say s2.object_id; #=> '30424504'
s2.name = 'bar'; # change name in s2
say s1.name; #=> 'bar'
Slate
Clones of Oddball themselves may not be cloned. Methods and slots may still be defined on them:
define: #Singleton &builder: [Oddball clone]
Smalltalk
SomeClass class>>sharedInstance
SharedInstance ifNil: [SharedInstance := self basicNew initialize].
^ SharedInstance
Swift
class SingletonClass {
static let sharedInstance = SingletonClass()
///Override the init method and make it private
private override init(){
// User can do additional manipulations here.
}
}
// Usage
let sharedObject = SingletonClass.sharedInstance
Tcl
or
package require TclOO
# This is a metaclass, a class that defines the behavior of other classes
oo::class create singleton {
superclass oo::class
variable object
unexport create ;# Doesn't make sense to have named singletons
method new args {
if {![info exists object]} {
set object [next {*}$args]
}
return $object
}
}
singleton create example {
method counter {} {
my variable count
return [incr count]
}
}
Demonstrating in an interactive shell:
% set a [example new]
::oo::Obj20
% set b [example new] ;# note how this returns the same object name
::oo::Obj20
% expr {$a == $b}
1
% $a counter
1
% $b counter
2
% $a counter
3
% $b counter
4
Tern
Tern has built-in support for singletons via module declarations.
module Singleton {
speak() {
println("I am a singleton");
}
}
Singleton.speak();
- Output:
I am a singleton
TXR
;; Custom (:singleton) clause which adds behavior to a class
;; asserting against multiple instantiation.
(define-struct-clause :singleton ()
^((:static inst-count 0)
(:postinit (me)
(assert (<= (inc me.inst-count) 1)))))
(defstruct singleton-one ()
(:singleton)
(:method speak (me)
(put-line "I am singleton-one")))
(defstruct singleton-two ()
(:singleton)
(:method speak (me)
(put-line "I am singleton-two")))
;; Test
;; Global singleton
(defvarl s1 (new singleton-one))
;; Local singleton in function (like static in C)
;; load-time evaluates once.
(defun fn ()
(let ((s2 (load-time (new singleton-two))))
s2.(speak)))
s1.(speak)
(fn) ;; multiple calls to fn don't re-instantiate singleton-two
(fn)
(put-line "so far, so good")
(new singleton-two) ;; assertion gooes off
- Output:
I am singleton-one I am singleton-two I am singleton-two so far, so good txr: unhandled exception of type assert: txr: assertion (<= (inc me.inst-count) 1) failed in singleton.tl:6 txr: during evaluation at singleton.tl:6 of form (sys:rt-assert-fail "singleton.tl" 6 '(<= (inc me.inst-count) 1))
Vala
public class Singleton : Object {
static Singleton? instance;
// Private constructor
Singleton() {
}
// Public constructor
public static Singleton get_instance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
void main() {
Singleton a = Singleton.get_instance();
Singleton b = Singleton.get_instance();
if (a == b) {
print("Equal.\n");
}
}
Wren
Although it's possible to create a singleton in Wren, you have to rely on no one calling the 'private' constructor directly. This is because there is currently no way to create a private method in Wren - all you can do is to suffix the name with an underscore to indicate by convention it's for internal use only.
In practice, it's unlikely anyone would bother; they'd just create a class with static methods and/or fields only which is effectively a singleton as there's only ever a single instance of a static field.
class Singleton {
// Returns the singleton. If it hasn't been created, creates it first.
static instance { __instance == null ? __instance = Singleton.new_() : __instance }
// Private constructor.
construct new_() {}
// instance method
speak() { System.print("I'm a singleton.") }
}
var s1 = Singleton.instance
var s2 = Singleton.instance
System.print("s1 and s2 are same object = %(Object.same(s1, s2))")
s1.speak() // call instance method
- Output:
s1 and s2 are same object = true I'm a singleton.
zkl
A class declared static only has one instance, ever. However, a class with the same name & structure could be created in another scope.
class [static] Borg{ var v }
b1 := Borg; b2 := Borg();
b1 == b2 //--> True
b1.v=123; b2.v.println(); //--> 123
- Programming Tasks
- Object oriented
- ActionScript
- Ada
- AutoHotkey
- BASIC
- FreeBASIC
- OxygenBasic
- PureBasic
- C
- C sharp
- C++
- Caché ObjectScript
- Common Lisp
- D
- Delphi
- Pascal
- E
- Ecstasy
- Eiffel
- Elena
- EMal
- Epoxy
- Erlang
- Factor
- Forth
- Go
- Groovy
- Unicon
- Io
- J
- Java
- JavaScript
- Julia
- Kotlin
- M2000 Interpreter
- Lasso
- Latitude
- Lingo
- Logtalk
- NetRexx
- Nim
- Objeck
- Objective-C
- Oforth
- OoRexx
- Oz
- Perl
- Phix
- Phix/Class
- PHP
- PicoLisp
- Python
- Racket
- Raku
- Ruby
- Scala
- Sidef
- Slate
- Smalltalk
- Swift
- Tcl
- TclOO
- Tern
- TXR
- Vala
- Wren
- Zkl
- 6502 Assembly/Omit
- 68000 Assembly/Omit
- 8086 Assembly/Omit
- ARM Assembly/Omit
- AWK/Omit
- GAP/Omit
- Haskell/Omit
- Icon/Omit
- LaTeX/Omit
- M4/Omit
- Mathematica/Omit
- Maxima/Omit
- Minimal BASIC/Omit
- Metafont/Omit
- Nascom BASIC/Omit
- OCaml/Omit
- Octave/Omit
- Palo Alto Tiny BASIC/Omit
- PARI/GP/Omit
- PL/0/Omit
- PlainTeX/Omit
- Retro/Omit
- Standard ML/Omit
- TI-83 BASIC/Omit
- TI-89 BASIC/Omit
- Tiny BASIC/Omit
- X86 Assembly/Omit
- Z80 Assembly/Omit
- ZX Spectrum Basic/Omit