Create an object/Native demonstration: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(17 intermediate revisions by 8 users not shown)
Line 1:
{{draft task}}
 
Create a Hash/Associative Array/Dictionary-like object, that can be initialized with some default key/value pairs using the languages native method of object creation. The object should behave like a native Hash/Associative Array/Dictionary of the language, if any, but with the following differences:
 
* No new itemkeys can be added;
* Keys cannot be removed;
* Item cannot be deleted, (but native delete method may used to reset the item's value to default) ;
* Attempting to delete a key should set that keys value back to that used during initialisation.
(The value assigned to keys may be changed by normal assignment however).
 
If the language supports '''Magic Methods''', then show how these work.
 
=={{header|BASIC}}==
==={{header|BASIC256}}===
<syntaxhighlight lang="basic256">map mapa
mapa["A"] = 65
mapa["B"] = 66
mapa["C"] = 67
 
foreach valor in mapa
print valor
print mapa[valor]
next valor</syntaxhighlight>
{{out}}
<pre>A
65
B
66
C
67</pre>
 
==={{header|FreeBASIC}}===
FB doesn't have Dict natively, but we can implement them via Type
<syntaxhighlight lang="freebasic">Type dict
m1 As String*1
m2 As Integer
End Type
 
Dim mapOf(1 To 3) As dict => {("A", 65), ("B", 66), ("C", 67)}
 
For i As Integer = 1 To Ubound(mapOf)
Print mapOf(i).m1
Print mapOf(i).m2
Next i</syntaxhighlight>
{{out}}
<pre>A
65
B
66
C
67</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <iostream>
#include <map>
#include <utility>
 
using namespace std;
 
template<typename T>
class FixedMap : private T
{
// Two standard maps are used to implement FixedMap. One as a private
// base class which will allow the values (but not the keys) to be modified.
// Members of a private base class are not exposed to the derived class which will
// prevent keys from being added or deleted. Another map will hold copies of
// the initial values.
T m_defaultValues;
public:
FixedMap(T map)
: T(map), m_defaultValues(move(map)){}
// Expose members of the base class that do not modify the map.
using T::cbegin;
using T::cend;
using T::empty;
using T::find;
using T::size;
 
// Also expose members that can modify values but not add or remove keys.
using T::at;
using T::begin;
using T::end;
// The [] operator will normally add a new key if the key is not already in the
// map. Instead, throw an error if the key is missing.
auto& operator[](typename T::key_type&& key)
{
// Make it behave like at()
return this->at(forward<typename T::key_type>(key));
}
// Instead of removing a key, change the sematics of erase() to restore
// the original value of the key.
void erase(typename T::key_type&& key)
{
T::operator[](key) = m_defaultValues.at(key);
}
 
// Also change the sematics of clear() to restore all keys
void clear()
{
// Reset the base class using the defaults
T::operator=(m_defaultValues);
}
};
 
// Print the contents of a map
auto PrintMap = [](const auto &map)
{
for(auto &[key, value] : map)
{
cout << "{" << key << " : " << value << "} ";
}
cout << "\n\n";
};
 
int main(void)
{
// Create a fixed map based on the standard map
cout << "Map intialized with values\n";
FixedMap<map<string, int>> fixedMap ({
{"a", 1},
{"b", 2}});
PrintMap(fixedMap);
cout << "Change the values of the keys\n";
fixedMap["a"] = 55;
fixedMap["b"] = 56;
PrintMap(fixedMap);
cout << "Reset the 'a' key\n";
fixedMap.erase("a");
PrintMap(fixedMap);
cout << "Change the values the again\n";
fixedMap["a"] = 88;
fixedMap["b"] = 99;
PrintMap(fixedMap);
cout << "Reset all keys\n";
fixedMap.clear();
PrintMap(fixedMap);
try
{
// Adding or retrieving a missing key is a run time error
cout << "Try to add a new key\n";
fixedMap["newKey"] = 99;
}
catch (exception &ex)
{
cout << "error: " << ex.what();
}
}
</syntaxhighlight>
{{out}}
<pre>Map intialized with values
{a : 1} {b : 2}
 
Change the values of the keys
{a : 55} {b : 56}
 
Reset the 'a' key
{a : 1} {b : 56}
 
Change the values the again
{a : 88} {b : 99}
 
Reset all keys
{a : 1} {b : 2}
 
Try to add a new key
error: map::at</pre>
 
=={{header|D}}==
{{trans|Python}}
<langsyntaxhighlight lang="d">struct DefaultAA(TK, TV) {
TV[TK] standard, current;
 
Line 42 ⟶ 209:
d.remove("a");
d.writeln; // ["a":1, "b":66]
}</langsyntaxhighlight>
{{out}}
<pre>["a":1, "b":2]
Line 54 ⟶ 221:
 
First create a sub-directory, romap, of the project directory and place the following package in it:
<langsyntaxhighlight lang="go">package romap
 
type Romap struct{ imap map[byte]int }
Line 78 ⟶ 245:
rom.imap[key] = 0 // default value of int
}
}</langsyntaxhighlight>
 
This package can now be imported and used within the main package as follows:
<langsyntaxhighlight lang="go">package main
 
import (
Line 103 ⟶ 270:
i, _ = rom.Get('C')
fmt.Println("'C' now maps to", i)
}</langsyntaxhighlight>
 
{{out}}
Line 115 ⟶ 282:
Given a list of keys and an associated list of values, the idiomatic way of expressing this concept in J would be:
 
<langsyntaxhighlight lang="j">lookup=: values {~ keys&i.</langsyntaxhighlight>
 
For example:
 
<langsyntaxhighlight lang="j"> lookup=: 10 20 30 40 50 {~ (;:'this is a test')&i.
lookup ;:'a test'
30 40</langsyntaxhighlight>
 
Notes:
Line 135 ⟶ 302:
Java supports unmodifiable maps, sets, lists, and other more specialized unmodifiable collections. In this example, we have a unmodifiable map. We first create an ordinary map, modify as needed, then call the <code>Collections.unmodifiableMap</code>. We can subsequently read the map, but modification is not permitted. The returned map will subsequently throw a <code>UnsupportedOperationException</code> exception if a mutation operator is called. Several are demonstrated below.
 
<langsyntaxhighlight lang="java">
import java.util.Collections;
import java.util.HashMap;
Line 180 ⟶ 347:
}
</syntaxhighlight>
</lang>
 
{out}}
Line 197 ⟶ 364:
{{works with|JavaScript|1.7}}
 
<langsyntaxhighlight lang="javascript">var keyError = new Error("Invalid Key Error (FixedKeyDict)") ;
 
function FixedKeyDict(obj)
Line 259 ⟶ 426:
return "FixedKeyDict{" + s + "}" ;
} ;
}</langsyntaxhighlight>
 
Test run:
 
<langsyntaxhighlight lang="javascript">
const BR = "<BR>\n"
 
Line 297 ⟶ 464:
pl("error test : " + e.message) ;
}
</syntaxhighlight>
</lang>
 
output :
Line 320 ⟶ 487:
 
=={{header|jq}}==
jq objects are JSON objects and can be created using JSON syntax, e.g. <langsyntaxhighlight lang="jq">{"language": "jq"}</langsyntaxhighlight>
Objects can also be created programmatically, e.g. <langsyntaxhighlight lang="jq">{"one": 1} + {"two": 2}</langsyntaxhighlight>
 
jq objects, however, are really just values: they are immutable, and cannot be "deleted" any more than the number 1 can be deleted.
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">
<lang Julia>
using BackedUpImmutable
 
Line 352 ⟶ 519:
@test fibr["a"] == 0
end
</syntaxhighlight>
</lang>
All tests pass.
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.2
 
fun main(args: Array<String>) {
Line 362 ⟶ 529:
val map = mapOf('A' to 65, 'B' to 66, 'C' to 67)
println(map)
}</langsyntaxhighlight>
 
{{out}}
Line 371 ⟶ 538:
=={{header|M2000 Interpreter}}==
{{trans|C sharp}}
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module CheckIt {
Class LockedHash {
Line 441 ⟶ 608:
}
Checkit
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">a[1] = "Do not modify after creation";
a[2] = "Native demonstration";
Protect[a];</langsyntaxhighlight>
Example usage:
<pre>a[3] = 2
Line 454 ⟶ 621:
=={{header|Nim}}==
We leverage native stdlib table as our own object by implementing limited actual native table functionalities.
<langsyntaxhighlight lang="nim">import tables, options
 
type
Line 495 ⟶ 662:
 
main()
</syntaxhighlight>
</lang>
{{output}}
<pre>
Line 502 ⟶ 669:
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">use strict;
<lang perl>package LockedHash;
 
use parent Tie::Hash;
package LockedHash;
use parent 'Tie::Hash';
use Carp;
use strict;
 
sub TIEHASH {
Line 545 ⟶ 713:
}
 
sub lock_hash :prototype(\%) {
my $ref = shift;
tie(%$ref, __PACKAGE__, %$ref);
Line 570 ⟶ 738:
# add a new key x: will die
eval { $h{x} = 1 };
if ($@) { print "Operation error: $@" }</langsyntaxhighlight>output:<syntaxhighlight lang="text">a => 3
b => 4
c => 5
Line 579 ⟶ 747:
operation error: Can't add key x at test.pl line 14
LockedHash::STORE('LockedHash=HASH(0x8cebe14)', 'x', 1) called at test.pl line 66
eval {...} called at test.pl line 66</langsyntaxhighlight>
 
=={{header|Phix}}==
There is no native "read-only" setting on phix dictionaries, so the following wraps a pair of them to
provide the requested functionality.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>enum STD, CUR
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
sequence fkds = {} -- fixed key dictionaries ;-)
<span style="color: #008080;">enum</span> <span style="color: #000000;">STD</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">CUR</span>
integer freelist = 0
<span style="color: #004080;">sequence</span> <span style="color: #000000;">fkds</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> <span style="color: #000080;font-style:italic;">-- fixed key dictionaries ;-)</span>
 
<span style="color: #004080;">integer</span> <span style="color: #000000;">freelist</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
procedure fkd_destroy(integer id)
integer {std,cur} = fkds[id]
<span style="color: #008080;">procedure</span> <span style="color: #000000;">fkd_destroy</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">id</span><span style="color: #0000FF;">)</span>
destroy_dict(std)
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">std</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cur</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fkds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">id</span><span style="color: #0000FF;">]</span>
destroy_dict(cur)
<span style="color: #7060A8;">destroy_dict</span><span style="color: #0000FF;">(</span><span style="color: #000000;">std</span><span style="color: #0000FF;">)</span>
fkds[id] = freelist
<span style="color: #7060A8;">destroy_dict</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cur</span><span style="color: #0000FF;">)</span>
freelist = id
<span style="color: #000000;">fkds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">id</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">freelist</span>
end procedure
<span style="color: #000000;">freelist</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">id</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
function fkd_new(sequence key_pairs)
integer std = new_dict(key_pairs),
<span style="color: #008080;">function</span> <span style="color: #000000;">fkd_new</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">key_pairs</span><span style="color: #0000FF;">)</span>
cur = new_dict(std),
<span style="color: #004080;">integer</span> <span style="color: #000000;">std</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">(</span><span style="color: #000000;">key_pairs</span><span style="color: #0000FF;">),</span>
id = freelist
<span style="color: #000000;">cur</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">(</span><span style="color: #000000;">std</span><span style="color: #0000FF;">),</span>
if id=0 then
<span style="color: #000000;">id</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">freelist</span>
fkds = append(fkds,{std,cur})
<span style="color: #008080;">if</span> <span style="color: #000000;">id</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
id = length(fkds)
<span style="color: #000000;">fkds</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fkds</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">std</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cur</span><span style="color: #0000FF;">})</span>
else
<span style="color: #000000;">id</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fkds</span><span style="color: #0000FF;">)</span>
freelist = fkds[id]
<span style="color: #008080;">else</span>
fkds[id] = {std,cur}
<span style="color: #000000;">freelist</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fkds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">id</span><span style="color: #0000FF;">]</span>
end if
<span style="color: #000000;">fkds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">id</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">std</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cur</span><span style="color: #0000FF;">}</span>
return id
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">id</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
procedure fkd_clear(integer id)
integer {std,cur} = fkds[id]
<span style="color: #008080;">procedure</span> <span style="color: #000000;">fkd_clear</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">id</span><span style="color: #0000FF;">)</span>
destroy_dict(cur)
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">std</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cur</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fkds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">id</span><span style="color: #0000FF;">]</span>
fkds[id][CUR] = new_dict(std)
<span style="color: #7060A8;">destroy_dict</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cur</span><span style="color: #0000FF;">)</span>
end procedure
<span style="color: #000000;">fkds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">id</span><span style="color: #0000FF;">][</span><span style="color: #000000;">CUR</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">(</span><span style="color: #000000;">std</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
function fkd_get(integer id, object key)
return getd(key,fkds[id][CUR])
<span style="color: #008080;">function</span> <span style="color: #000000;">fkd_get</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">id</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000000;">key</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">return</span> <span style="color: #7060A8;">getd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">key</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fkds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">id</span><span style="color: #0000FF;">][</span><span style="color: #000000;">CUR</span><span style="color: #0000FF;">])</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
procedure fkd_set(integer id, object key, data)
integer node = getd_index(key,fkds[id][CUR])
<span style="color: #008080;">procedure</span> <span style="color: #000000;">fkd_set</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">id</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000000;">key</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">data</span><span style="color: #0000FF;">)</span>
if node=NULL then throw("invalid/new key") end if
<span style="color: #004080;">integer</span> <span style="color: #000000;">node</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">key</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fkds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">id</span><span style="color: #0000FF;">][</span><span style="color: #000000;">CUR</span><span style="color: #0000FF;">])</span>
setd(key,data,fkds[id][CUR])
<span style="color: #008080;">if</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span> <span style="color: #008080;">throw</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"invalid/new key"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end procedure
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">key</span><span style="color: #0000FF;">,</span><span style="color: #000000;">data</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fkds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">id</span><span style="color: #0000FF;">][</span><span style="color: #000000;">CUR</span><span style="color: #0000FF;">])</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
procedure fkd_remove(integer id, object key)
integer {std,cur} = fkds[id],
<span style="color: #008080;">procedure</span> <span style="color: #000000;">fkd_remove</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">id</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000000;">key</span><span style="color: #0000FF;">)</span>
node = getd_index(key,std)
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">std</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cur</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fkds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">id</span><span style="color: #0000FF;">],</span>
if node=NULL then throw("invalid key") end if
<span style="color: #000000;">node</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">key</span><span style="color: #0000FF;">,</span><span style="color: #000000;">std</span><span style="color: #0000FF;">)</span>
setd(key,getd_by_index(node,std),cur)
<span style="color: #008080;">if</span> <span style="color: #000000;">node</span><span style="color: #0000FF;">=</span><span style="color: #004600;">NULL</span> <span style="color: #008080;">then</span> <span style="color: #008080;">throw</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"invalid key"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end procedure
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">key</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">getd_by_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">node</span><span style="color: #0000FF;">,</span><span style="color: #000000;">std</span><span style="color: #0000FF;">),</span><span style="color: #000000;">cur</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
function fkd_sprint(integer id)
integer cur = fkds[id][CUR]
<span style="color: #008080;">function</span> <span style="color: #000000;">fkd_sprint</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">id</span><span style="color: #0000FF;">)</span>
sequence res = getd_all_keys(cur)
<span style="color: #004080;">integer</span> <span style="color: #000000;">cur</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fkds</span><span style="color: #0000FF;">[</span><span style="color: #000000;">id</span><span style="color: #0000FF;">][</span><span style="color: #000000;">CUR</span><span style="color: #0000FF;">]</span>
for i=1 to length(res) do
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd_all_keys</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cur</span><span style="color: #0000FF;">)</span>
object ri = res[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
res[i] = {ri,getd(ri,cur)}
<span style="color: #004080;">object</span> <span style="color: #000000;">ri</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
end for
<span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">getd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cur</span><span style="color: #0000FF;">)}</span>
return res
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
procedure main()
integer id = fkd_new({{"a",1},{"b",2}})
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
?fkd_sprint(id) -- {{"a",1},{"b",2}}
<span style="color: #004080;">integer</span> <span style="color: #000000;">id</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fkd_new</span><span style="color: #0000FF;">({{</span><span style="color: #008000;">"a"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #008000;">"b"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}})</span>
fkd_set(id,"a",55)
<span style="color: #0000FF;">?</span><span style="color: #000000;">fkd_sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- {{"a",1},{"b",2}}</span>
fkd_set(id,"b",66)
<span style="color: #000000;">fkd_set</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"a"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">55</span><span style="color: #0000FF;">)</span>
?fkd_sprint(id) -- {{"a",55},{"b",66}}
<span style="color: #000000;">fkd_set</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"b"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">66</span><span style="color: #0000FF;">)</span>
fkd_clear(id)
<span style="color: #0000FF;">?</span><span style="color: #000000;">fkd_sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- {{"a",155},{"b",266}}</span>
<span style="color: #000000;">fkd_clear</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">)</span>
fkd_set(id,"a",55)
<span style="color: #0000FF;">?</span><span style="color: #000000;">fkd_sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- {{"a",1},{"b",2}}</span>
fkd_set(id,"b",66)
<span style="color: #000000;">fkd_set</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"a"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">55</span><span style="color: #0000FF;">)</span>
?fkd_get(id,"a") -- 55
<span style="color: #000000;">fkd_set</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"b"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">66</span><span style="color: #0000FF;">)</span>
fkd_remove(id,"a")
<span style="color: #0000FF;">?</span><span style="color: #000000;">fkd_get</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"a"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- 55</span>
try
<span style="color: #000000;">fkd_remove</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"a"</span><span style="color: #0000FF;">)</span>
fkd_set(id,"NoNewKey",77)
<span style="color: #008080;">try</span>
catch e
<span style="color: #000000;">fkd_set</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"NoNewKey"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">77</span><span style="color: #0000FF;">)</span>
?e[E_USER] -- "invalid/new key"
<span style="color: #008080;">catch</span> <span style="color: #000000;">e</span>
end try
<span style="color: #0000FF;">?</span><span style="color: #000000;">e</span><span style="color: #0000FF;">[</span><span style="color: #004600;">E_USER</span><span style="color: #0000FF;">]</span> <span style="color: #000080;font-style:italic;">-- "invalid/new key"</span>
?fkd_sprint(id) -- {{"a",1},{"b",66}}
<span style="color: #008080;">end</span> <span style="color: #008080;">try</span>
fkd_destroy(id)
<span style="color: #0000FF;">?</span><span style="color: #000000;">fkd_sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- {{"a",1},{"b",66}}</span>
end procedure
<span style="color: #000000;">fkd_destroy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">id</span><span style="color: #0000FF;">)</span>
main()</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">
from collections import UserDict
import copy
Line 753 ⟶ 924:
raise KeyError
else:
return super().setdefault(key, default)</langsyntaxhighlight>
 
=={{header|Racket}}==
Line 760 ⟶ 931:
 
Implementation of functions that handle fenced-hash:
<syntaxhighlight lang="racket">
<lang Racket>
;(struct fenced-hash (actual original) ...)
 
Line 798 ⟶ 969:
;private custom-write ;mode is ignored
(write-string "#fenced-hash" port)
(write (hash->list (fenced-hash-actual dict)) port))</langsyntaxhighlight>
 
Definition of the actual structure and a “public” creator:
<langsyntaxhighlight Racketlang="racket">(struct fenced-hash (actual original)
#:extra-constructor-name *fenced-hash ;private constructor
#:omit-define-syntaxes ;not sure this is a good idea
Line 821 ⟶ 992:
(define (fenced-hash . args) ; public constructor
(define original (apply hash args))
(*fenced-hash (hash-copy original) original))</langsyntaxhighlight>
 
'''Example:''' Use the fenced-hash functions:
<langsyntaxhighlight Racketlang="racket">(define d (fenced-hash "a" 1 "b" 2))
 
(displayln d)
Line 836 ⟶ 1,007:
(displayln d)
(fenced-hash-remove! d "a")
(displayln d)</langsyntaxhighlight>
{{out}}
<pre>#fenced-hash(("b" . 2) ("a" . 1))
Line 845 ⟶ 1,016:
 
'''Example (continued):''' Use the same object as a dict. The dict-clear! method is not defined, so we must call fenced-hash-clear! instead.
<langsyntaxhighlight Racketlang="racket">(fenced-hash-clear! d)
(displayln d)
(dict-set! d "a" 55)
Line 856 ⟶ 1,027:
(displayln d)
(dict-remove! d "a")
(displayln d)</langsyntaxhighlight>
{{out}}
<pre>#fenced-hash(("b" . 2) ("a" . 1))
Line 868 ⟶ 1,039:
{{Works with|rakudo|2016.08}}
Here we use delegation to handle all the normal hash methods that we don't need to override to define our new class.
<syntaxhighlight lang="raku" perl6line>class FixedHash {
has $.hash handles *;
method new(*@args) { self.bless: hash => Hash.new: @args }
Line 886 ⟶ 1,057:
say $fh<c>; # Nil
$fh<c> = 43; # error
</syntaxhighlight>
</lang>
{{out}}
<pre>(1 2)
Line 897 ⟶ 1,068:
in block <unit> at native-demonstration.p6:17</pre>
 
By defining [http://design.perl6raku.org/S12.html#FALLBACK_methods FALLBACK] any class can handle undefined method calls. Since any class inherits plenty of methods from <tt>Any</tt> our magic object will be more of a novice conjurer then a master wizard proper.
 
<syntaxhighlight lang="raku" perl6line>class Magic {
has %.hash;
multi method FALLBACK($name, |c) is rw { # this will eat any extra parameters
Line 913 ⟶ 1,084:
$magic.foo = 10;
say $magic.foo;
$magic.defined = False; # error</langsyntaxhighlight>
 
{{output}}
Line 921 ⟶ 1,092:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Create an object/Native demonstration
 
Line 929 ⟶ 1,100:
map["C"] = 67
see map + nl
</syntaxhighlight>
</lang>
Output:
<pre>
Line 942 ⟶ 1,113:
=={{header|Ruby}}==
{{works with|Ruby|1.9}}
<langsyntaxhighlight lang="ruby"># A FencedHash acts like a Hash, but with a fence around its keys.
# One may change its values, but not its keys. Any attempt to insert
# a new key raises KeyError. One may delete a key, but this only
Line 1,185 ⟶ 1,356:
keys.map {|key| self[key]}
end
end</langsyntaxhighlight>
 
=={{header|Scala}}==
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/OuVZ3bT/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/qW5qzmdKSZSyAbZEqDROoA Scastie (remote JVM)].
<langsyntaxhighlight Scalalang="scala">object CreateMapObject extends App {
val map = Map('A' -> 65, 'B' -> 66, 'C' -> 67)
 
println(map)
}</langsyntaxhighlight>
 
=={{header|Tcl}}==
This solution uses a dict(ionary), so requires Tcl 8.5 or better. Variable traces are used to detect write or unset access to such a protected variable, restore it to the backup value at protection time, and throw an exception
 
<langsyntaxhighlight Tcllang="tcl">proc protect _var {
upvar 1 $_var var
trace add variable var {write unset} [list protect0 $var]
Line 1,212 ⟶ 1,383:
puts "trying: $cmd"
if [catch {uplevel 1 $cmd} msg] {puts $msg}
}</langsyntaxhighlight>
Testing:
dict set dic 1 one
Line 1,233 ⟶ 1,404:
trying: unset dic
dic:1 one 2 two
 
=={{header|Wren}}==
<syntaxhighlight lang="wren">class FixedSizeMap {
construct new(map) {
// copy the map so it cannot be mutated from the original reference
_map = {}
for (me in map.toList) _map[me.key] = me.value
}
 
containsKey(key) { _map[key] != null }
 
count { _map.count }
 
keys { _map.keys }
 
values { _map.values }
 
[key] { _map[key] }
[key] =(value) {
// do nothing if key doesn't already exist
if (_map[key] != null) _map[key] = value
}
 
reset(key) {
var t = _map[key].type
// leave unaltered if no suitable default value
_map[key] = (t == Num) ? 0 :
(t == String) ? "":
(t == Bool) ? false :
(t == List) ? [] :
(t == Map) ? {} : _map[key]
}
 
iterate(iterator) { _map.iterate(iterator) }
iteratorValue(iterator) { _map.iteratorValue(iterator) }
 
toString { _map.toString }
}
 
var map = { "a": 1, "b": 2 }
var fsm = FixedSizeMap.new(map)
System.print(fsm)
System.print(fsm.count)
fsm["a"] = 3
fsm["b"] = 4
System.print(fsm)
System.print(fsm.containsKey("c"))
fsm["c"] = 5 // attempt to add a new key/value pair
System.print(fsm) // ignored
fsm.reset("a")
System.print(fsm)
System.print(fsm.keys.toList)
System.print(fsm.values.toList)
for (me in fsm) System.print([me.key, me.value])
</syntaxhighlight>
 
{{out}}
<pre>
{b: 2, a: 1}
2
{b: 4, a: 3}
false
{b: 4, a: 3}
{b: 4, a: 0}
[b, a]
[4, 0]
[b, 4]
[a, 0]
</pre>
 
=={{header|zkl}}==
zkl has two dictionary objects: SD, a small dictionary that is created immutable and the "regular" dictionary has has a makeReadOnly method. They both behave the same when locked down.
<langsyntaxhighlight lang="zkl">d:=SD("one",1,"two",2);
d.keys; //-->L("one","two")
d["one"]; //-->1
d.add("three",3); // error thrown
d.pop("one") // error thrown</langsyntaxhighlight>
 
 
9,476

edits