Multiton: Difference between revisions

3,994 bytes added ,  2 months ago
Added Python
m (→‎{{header|Phix}}: new_dict remark)
(Added Python)
 
(8 intermediate revisions by 4 users not shown)
Line 17:
=={{header|Julia}}==
A registry (just in memory, not on disk) is used below instead of an enum. The registry is protected by a lock on the Multiton constructor, to prevent two threads creating the same object at the same time.
<langsyntaxhighlight lang="julia">struct Multiton{T}
data::T
function Multiton(registry, refnum, data)
lock(registry.spinlock)
if 0 < refnum <= registry.max_instances && registry.instances[refnum] isa Nothing
lock(registry.spinlock)
multiton = new{typeof(data)}(data)
registry.instances[refnum] = multiton
Line 27:
return multiton
else
unlock(registry.spinlock)
error("Cannot create instance with instance reference number $refnum")
end
Line 63 ⟶ 64:
# produce error
m5 = Multiton(reg, 5)
</langsyntaxhighlight>{{out}}
<pre>
Multiton is Multiton{String}("zero")
Line 71 ⟶ 72:
Multiton is Multiton{Float64}(1.0)
ERROR: LoadError: Cannot find a Multiton in registry with instance reference number 5
</pre>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl"># 20211215 Perl programming solution
 
use strict;
use warnings;
 
BEGIN {
package MultitonDemo ;
use Moo;
with 'Role::Multiton';
has [qw(attribute)] => ( is => 'rw');
$INC{"MultitonDemo.pm"} = 1;
}
 
use MultitonDemo;
 
print "We create several instances and compare them to see if multiton is in effect.\n";
print "\n";
print "Instance Constructor Attribute\n";
print "\n";
print "0 multiton 0\n";
print "1 multiton 1\n";
print "2 multiton 0\n";
print "3 new 0\n";
print "4 new 0\n";
 
my $inst0 = MultitonDemo->multiton (attribute => 0);
my $inst1 = MultitonDemo->multiton (attribute => 1);
my $inst2 = MultitonDemo->multiton (attribute => 0);
my $inst3 = MultitonDemo->new (attribute => 0);
my $inst4 = MultitonDemo->new (attribute => 0);
 
print "\n";
if ($inst0 eq $inst1) { print "Instance0 and Instance1 share the same object\n" };
if ($inst1 eq $inst2) { print "Instance1 and Instance2 share the same object\n" };
if ($inst0 eq $inst2) { print "Instance0 and Instance2 share the same object\n" };
if ($inst0 eq $inst3) { print "Instance0 and Instance3 share the same object\n" };
if ($inst3 eq $inst4) { print "Instance3 and Instance4 share the same object\n" };</syntaxhighlight>
{{out}}
<pre>We create several instances and compare them to see if multiton is in effect.
 
Instance Constructor Attribute
 
0 multiton 0
1 multiton 1
2 multiton 0
3 new 0
4 new 0
 
Instance0 and Instance2 share the same object
</pre>
 
Line 80 ⟶ 133:
Put this (up to "end class") in a separate file, to keep allowed and instances private. Classes are not [yet] supported under pwa/p2js.<br>
Technically I suppose this should really use new_dict()/getd()/setd(), but I'm quite sure you'll cope somehow..
<!--<langsyntaxhighlight Phixlang="phix">(notonline)-->
<span style="color: #008080;">without</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">allowed</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"zero"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"one"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"two"</span><span style="color: #0000FF;">},</span>
Line 113 ⟶ 166:
<span style="color: #0000FF;">?</span><span style="color: #000000;">e</span><span style="color: #0000FF;">.</span><span style="color: #000000;">id</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">f</span><span style="color: #0000FF;">.</span><span style="color: #000000;">id</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 122 ⟶ 175:
"one_111"
"two_544"
</pre>
 
=={{header|Python}}==
{{works with|Python|3.x}}
<syntaxhighlight lang="python">#!/usr/bin/python
 
import threading
 
class Multiton:
def __init__(self, registry, refnum, data=None):
with registry.lock:
if 0 < refnum <= registry.max_instances and registry.instances[refnum] is None:
self.data = data
registry.instances[refnum] = self
elif data is None and 0 < refnum <= registry.max_instances and isinstance(registry.instances[refnum], Multiton):
self.data = registry.instances[refnum].data
else:
raise Exception("Cannot create or find instance with instance reference number {}".format(refnum))
 
class Registry:
def __init__(self, maxnum):
self.lock = threading.Lock()
self.max_instances = maxnum
self.instances = [None] * maxnum
 
reg = Registry(3)
m0 = Multiton(reg, 1, "zero")
m1 = Multiton(reg, 2, 1.0)
m2 = Multiton(reg, 1)
m3 = Multiton(reg, 2)
 
for m in [m0, m1, m2, m3]:
print("Multiton is {}".format(m.data))
 
 
# produce error
#m2 = Multiton(reg, 3, [2])
 
# produce error
# m3 = Multiton(reg, 4, "three")
 
# produce error
# m5 = Multiton(reg, 5)</syntaxhighlight>
 
=={{header|Raku}}==
Tried to translate [https://wikipedia.org/wiki/Multiton_pattern#Implementations the C# example] at WP but not sure if my interpretation/implementation is correct
<syntaxhighlight lang="raku" line># 20211001 Raku programming solution
 
enum MultitonType < Gold Silver Bronze >;
 
class Multiton {
 
my %instances = MultitonType.keys Z=> $ ⚛= 1 xx * ;
 
has $.type is rw;
 
method TWEAK { $.type = 'Nothing' unless cas(%instances{$.type}, 1, 0) }
}
 
race for ^10 -> $i {
Thread.start(
sub {
# sleep roll(^2);
my $obj = Multiton.new: type => MultitonType.roll;
say "Thread ", $i, " has got ", $obj.type;
}
);
}</syntaxhighlight>
{{out}}
<pre>
Thread 5 has got Bronze
Thread 9 has got Gold
Thread 7 has got Nothing
Thread 8 has got Nothing
Thread 3 has got Nothing
Thread 2 has got Nothing
Thread 1 has got Nothing
Thread 0 has got Silver
Thread 4 has got Nothing
Thread 6 has got Nothing
</pre>
 
Line 129 ⟶ 262:
 
Although all Wren code runs within the context of a fiber (of which there can be thousands) only one fiber can run at a time and so the language is effectively single threaded. Thread-safety is therefore never an issue.
<langsyntaxhighlight ecmascriptlang="wren">import "./dynamic" for Enum
 
var MultitonType = Enum.create("MultitonType", ["zero", "one", "two"])
Line 161 ⟶ 294:
System.print(m2)
 
var m3 = Multiton.getInstance(3) // produces an error</langsyntaxhighlight>
 
{{out}}
2,122

edits