Skip to content

Instantly share code, notes, and snippets.

@tadzik
Created March 10, 2012 13:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tadzik/2011428 to your computer and use it in GitHub Desktop.
Save tadzik/2011428 to your computer and use it in GitHub Desktop.
diff --git a/src/core/Set.pm b/src/core/Set.pm
index c7e8afe..2925def 100644
--- a/src/core/Set.pm
+++ b/src/core/Set.pm
@@ -1,6 +1,8 @@
-my class Set is Iterable does Associative {
+my role Settish is Iterable {
has %!elems;
+ method !storage { %!elems }
+
method keys { %!elems.keys }
method values { %!elems.values }
method elems returns Int { %!elems.elems }
@@ -11,27 +13,37 @@ my class Set is Iterable does Associative {
method at_key($k) { ?(%!elems{$k} // False) }
method exists_key($k) { self.exists($k) }
- # Constructor
- method new(*@args --> Set) {
+ method new(*@args) {
my %e;
- sub register-arg($arg) {
- given $arg {
- when Pair { %e{.key} = True; }
- when Set | KeySet { for .keys -> $key { %e{$key} = True; } }
- when Associative { for .pairs -> $p { register-arg($p); } }
- when Positional { for .list -> $p { register-arg($p); } }
- default { %e{$_} = True; }
- }
- }
-
for @args {
- register-arg($_);
+ self.register-arg($_, %e);
}
- self.bless(*, :elems(%e));
+ self.bless(*, :elems(%e))
}
submethod BUILD (:%!elems) { }
+ method iterator() { %!elems.keys.iterator }
+ method list() { %!elems.keys }
+ method pick($count = 1) { %!elems.keys.pick($count) }
+ method roll($count = 1) { %!elems.keys.roll($count) }
+}
+
+my class Set does Associative does Settish {
+ method register-arg($arg, %e is rw) {
+ given $arg {
+ when Pair { %e{.key} = True; }
+ when Set | KeySet { for .keys -> $key { %e{$key} = True; } }
+ when Associative {
+ for .pairs -> $p { self.register-arg($p, %e) }
+ }
+ when Positional {
+ for .list -> $p { self.register-arg($p, %e) }
+ }
+ default { %e{$_} = True; }
+ }
+ }
+
# Coercions to and from
method postcircumfix:<( )> ($s --> Set) { to-set($s) }
multi to-set (Set $set --> Set) { $set }
@@ -43,15 +55,15 @@ my class Set is Iterable does Associative {
multi to-set (%elems --> Set) { Set.new: %elems.keys }
multi to-set ($elem --> Set) { die "Cannot coerce $elem.perl() to a Set; use set($elem.perl()) to create a one-element set" }
- multi method Str(Any:D $ : --> Str) { "set(< %!elems.keys() >)" }
- multi method gist(Any:D $ : --> Str) { "set({ %!elems.keys».gist.join(', ') })"
+ multi method Str(Any:D $ : --> Str) {
+ "set(< {self!storage.keys()} >)"
+ }
+ multi method gist(Any:D $ : --> Str) {
+ "set({ self!storage.keys».gist.join(', ') })"
+ }
+ multi method perl(Any:D $ : --> Str) {
+ 'set(' ~ join(', ', map { .perl }, self!storage.keys) ~ ')'
}
- multi method perl(Any:D $ : --> Str) { 'set(' ~ join(', ', map { .perl }, %!elems.keys) ~ ')' }
-
- method iterator() { %!elems.keys.iterator }
- method list() { %!elems.keys }
- method pick($count = 1) { %!elems.keys.pick($count) }
- method roll($count = 1) { %!elems.keys.roll($count) }
# TODO: WHICH will require the capability for >1 pointer in ObjAt
}
@@ -60,50 +72,38 @@ sub set(*@args) {
Set.new(@args);
}
-my class KeySet is Iterable does Associative {
- has %!elems;
-
- method keys { %!elems.keys }
- method values { %!elems.values }
- method elems returns Int { %!elems.elems }
- method exists($a) returns Bool { %!elems.exists($a) && %!elems{$a} }
- method Bool { %!elems.Bool }
- method Numeric { %!elems.Numeric }
- method hash { %!elems.hash }
+my class KeySet does Associative does Settish {
+ method exists($a) returns Bool {
+ self!storage.exists($a) && self!storage{$a}
+ }
method at_key($k) {
- Proxy.new(FETCH => { %!elems.exists($k) ?? True !! False },
- STORE => -> $, $value { if $value { %!elems{$k} = True } else { %!elems.delete($k) }});
+ Proxy.new(FETCH => { self!storage.exists($k) ?? True !! False },
+ STORE => -> $, $value {
+ if $value { self!storage{$k} = True }
+ else { self!storage.delete($k) }
+ });
}
- method exists_key($k) { self.exists($k) }
- method delete_key($k) { %!elems.delete($k) }
-
- # Constructor
- method new(*@args --> KeySet) {
- my %e;
- sub register-arg($arg) {
- given $arg {
- when Pair { %e{.key} = True; }
- when Set | KeySet { for .keys -> $key { %e{$key} = True; } }
- when Associative { for .pairs -> $p { register-arg($p); } }
- when Positional { for .list -> $p { register-arg($p); } }
- default { %e{$_} = True; }
+ method delete_key($k) { self!storage.delete($k) }
+
+ method register-arg($arg, %e is rw) {
+ given $arg {
+ when Pair { %e{.key} = True; }
+ when Set | KeySet { for .keys -> $key { %e{$key} = True; } }
+ when Associative {
+ for .pairs -> $p { self.register-arg($p, %e) }
}
+ when Positional {
+ for .list -> $p { self.register-arg($p, %e) }
+ }
+ default { %e{$_} = True; }
}
-
- for @args {
- register-arg($_);
- }
- self.bless(*, :elems(%e));
}
- submethod BUILD (:%!elems) { }
-
- submethod Str(Any:D $ : --> Str) { "keyset(< %!elems.keys() >)" }
- submethod gist(Any:D $ : --> Str) { "keyset({ %!elems.keys».gist.join(', ') })" }
- submethod perl(Any:D $ : --> Str) { 'KeySet.new(' ~ join(', ', map { .perl }, %!elems.keys) ~ ')' }
-
- method iterator() { %!elems.keys.iterator }
- method list() { %!elems.keys }
- method pick($count = 1) { %!elems.keys.pick($count) }
- method roll($count = 1) { %!elems.keys.roll($count) }
+ multi method Str { "keyset(< {self!storage.keys()} >)" }
+ multi method gist {
+ "keyset({ self!storage.keys».gist.join(', ') })"
+ }
+ multi method perl {
+ 'KeySet.new(' ~ self!storage.keys.map({.perl}).join(', ') ~ ')'
+ }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment