Singleton: Difference between revisions
m omit from Retro |
|||
Line 826: | Line 826: | ||
{{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|Retro|No OOP}} |
Revision as of 02:24, 13 October 2010
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
<lang 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 {}</lang>
Ada
Non Thread Safe
<lang ada>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;</lang>
<lang ada>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;</lang>
Thread Safe
<lang ada>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;</lang>
<lang ada>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;</lang>
AutoHotkey
Translation of python borg pattern <lang AutoHotkey> 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
}</lang>
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. <lang c>#ifndef SILLY_H
- define SILLY_H
extern void JumpOverTheDog( int numberOfTimes); extern int PlayFetchWithDog( float weightOfStick);
- endif</lang>
Then in a separate C source (.c) file, define your structures, variables and functions. <lang c>...
- 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){...
}</lang> 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. <lang c>...
- include "silly.h"
... /* code using the dog methods */
JumpOverTheDog( 4); retrieved = PlayFetchWithDog( 3.1);
...</lang>
C++
Thread-safe
Operating System: Microsoft Windows NT/XP/Vista
<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, but it is not safe in a multi-threaded environment.
<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>
C#
Thread save singleton implementation. To make it non thread safe remove lockObject and the lock() statement
<lang csharp> // Usage: Singleton.Instance.SomeMethod() class Singleton {
private static Singleton _singleton; private static lockObject = new object(); private Singleton() {} public static Singleton Instance { get { lock(lockObject) { if (_singleton == null) _singleton = new Singleton(); } return _singleton; } } // The rest of the methods
} </lang>
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.
<lang Erlang> -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.
</lang>
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).
<lang Erlang> 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} </lang>
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.
<lang lisp>(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))))))))</lang>
Thread safety is irrelevant since the singleton is created at load time, not first access.
D
<lang 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 ;
}</lang> Sample 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
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).
<lang e>def aSingleton {
# ...
}</lang>
Factor
<lang factor>USING: classes.singleton kernel io prettyprint ; IN: singleton-demo
SINGLETON: bar GENERIC: foo ( obj -- ) M: bar foo drop "Hello!" print ; </lang>
( scratchpad ) bar foo Hello!
Icon and Unicon
Icon
Icon is not object oriented.
Unicon
<lang unicon>class Singleton
method print() write("Hi there.") end initially write("In constructor!") Singleton := create |self
end
procedure main()
Singleton().print() Singleton().print()
end</lang>
This 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: <lang io>Singleton := Object clone Singleton clone = Singleton</lang>
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.)
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
Double-checked locking; only use with Java 1.5+ <lang java>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
}</lang>
Non-Thread-Safe
<lang java>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
}</lang>
Perl 6
<lang Perl6>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; }
}</lang>
PHP
<lang 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</lang>
PicoLisp
As there is no physical difference between classes and objects, we can use the class symbol itself. <lang PicoLisp>(class +Singleton)
(dm message1> ()
(prinl "This is method 1 on " This) )
(dm message2> ()
(prinl "This is method 2 on " This) )</lang>
Output:
: (message1> '+Singleton) This is method 1 on +Singleton -> +Singleton : (message2> '+Singleton) This is method 2 on +Singleton -> +Singleton
Python
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: <lang python>>>> 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!</lang>
Objeck
<lang objeck> class Singleton {
@singleton : static : Singleton;
New : private () { }
function : GetInstance() ~ Singleton { if(@singleton <> Nil) { @singleton := Singleton->New(); };
return @singleton; }
method : public : DoStuff() ~ Nil { ... }
} </lang>
Objective-C
Non-Thread-Safe
(Using Cocoa/OpenStep's NSObject as a base class) <lang objc>// SomeSingleton.h @interface SomeSingleton : NSObject {
// any instance variables
}
+ (SomeSingleton*)sharedInstance;
@end</lang>
<lang objc>// SomeSingleton.m @implementation SomeSingleton
+ (SomeSingleton*) sharedInstance {
static 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;
}
- (void)release {
// prevent release
}
- (id)autorelease {
return self;
}
@end</lang>
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.
<lang oz>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</lang>
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".
Ruby
<lang 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"</lang>
Scala
The object construct in Scala is a singleton.
<lang scala>object Singleton {
// any code here gets executed as if in a constructor
}</lang>
Slate
Clones of Oddball themselves may not be cloned. Methods and slots may still be defined on them: <lang slate>define: #Singleton &builder: [Oddball clone]</lang>
Tcl
or
ref http://wiki.tcl.tk/21595 <lang tcl>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] }
}</lang> Demonstrating in an interactive shell <lang tcl>% 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</lang>
- Programming Tasks
- Object oriented
- ActionScript
- Ada
- AutoHotkey
- C
- C++
- C sharp
- Erlang
- Common Lisp
- D
- E
- Factor
- Icon
- Unicon
- Io
- J
- Java
- Perl 6
- PHP
- PicoLisp
- Python
- Objeck
- Objective-C
- Oz
- PureBasic/Omit
- Ruby
- Scala
- Slate
- Tcl
- TclOO
- AWK/Omit
- Metafont/Omit
- M4/Omit
- LaTeX/Omit
- PlainTeX/Omit
- OCaml/Omit
- Haskell/Omit
- Octave/Omit
- TI-83 BASIC/Omit
- TI-89 BASIC/Omit
- Retro/Omit