Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Other changes to make type objects appear as Nil in non-scalar contexts
This typically makes something like:
  my Hash @A; say @A[42].elems  # returns 0
instead of blowing up or saying there is 1 element with the type object.
  • Loading branch information
lizmat committed Jul 24, 2013
1 parent d12ecc5 commit c3a58f9
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 17 deletions.
28 changes: 16 additions & 12 deletions src/core/EnumMap.pm
Expand Up @@ -5,8 +5,10 @@ my class EnumMap does Associative {
multi method Bool(EnumMap:D:) {
nqp::p6bool(nqp::defined($!storage) ?? nqp::elems($!storage) !! 0)
}
method elems(EnumMap:D:) {
nqp::defined($!storage) ?? nqp::p6box_i(nqp::elems($!storage)) !! 0
method elems(EnumMap:) {
self.DEFINITE && nqp::defined($!storage)
?? nqp::p6box_i(nqp::elems($!storage))
!! 0
}

multi method ACCEPTS(EnumMap:D: Any $topic) {
Expand All @@ -26,6 +28,7 @@ my class EnumMap does Associative {
}

proto method exists(|) {*}
multi method exists(EnumMap:U:) { False }
multi method exists(EnumMap:D: Str:D \key) {
nqp::p6bool(
nqp::defined($!storage)
Expand All @@ -45,14 +48,15 @@ my class EnumMap does Associative {
~ ')';
}

method iterator(EnumMap:D:) { self.pairs.iterator }
method list(EnumMap:D:) { self.pairs }
method iterator(EnumMap:) { self.pairs.iterator }
method list(EnumMap:) { self.pairs }

method keys(EnumMap:D:) { self.pairs.map( { $_.key } ) }
method kv(EnumMap:D:) { self.pairs.map( { $_.kv } ) }
method values(EnumMap:D:) { self.pairs.map( { $_.value } ) }
method pairs(EnumMap:D:) {
return unless nqp::defined($!storage);
method keys(EnumMap:) { self.pairs.map( { $_.key } ) }
method kv(EnumMap:) { self.pairs.map( { $_.kv } ) }
method values(EnumMap:) { self.pairs.map( { $_.value } ) }

method pairs(EnumMap:) {
return unless self.DEFINITE && nqp::defined($!storage);
gather {
my Mu $iter := nqp::iterator($!storage);
my Mu $pair;
Expand All @@ -68,8 +72,8 @@ my class EnumMap does Associative {
Nil
}
}
method invert(EnumMap:D:) {
return unless nqp::defined($!storage);
method invert(EnumMap:) {
return unless self.DEFINITE && nqp::defined($!storage);
gather {
my Mu $iter := nqp::iterator($!storage);
my Mu $pair;
Expand Down Expand Up @@ -112,7 +116,7 @@ my class EnumMap does Associative {
$!storage
}

method fmt(EnumMap:D: $format = "%s\t\%s", $sep = "\n") {
method fmt(EnumMap: $format = "%s\t\%s", $sep = "\n") {
self.pairs.fmt($format, $sep);
}

Expand Down
1 change: 1 addition & 0 deletions src/core/Hash.pm
Expand Up @@ -69,6 +69,7 @@ my class Hash {
}

proto method delete(|) { * }
multi method delete(Hash:U:) { Nil }
multi method delete($key as Str) {
my Mu $val = self.at_key($key);
nqp::deletekey(
Expand Down
17 changes: 12 additions & 5 deletions src/core/List.pm
Expand Up @@ -96,18 +96,21 @@ my class List does Positional {
method eager() { self.gimme(*); self }

method elems() {
return 0 unless self.DEFINITE;
# Get as many elements as we can. If gimme stops before
# reaching the end of the list, assume the list is infinite.
my $n = self.gimme(*);
$!nextiter.defined ?? $Inf !! $n
}

method exists(\pos) {
return False unless self.DEFINITE;
self.gimme(pos + 1);
nqp::p6bool(nqp::existspos($!items, nqp::unbox_i(pos)))
}

method gimme($n, :$sink) {
return unless self.DEFINITE;
# loop through iterators until we have at least $n elements
my int $count = nqp::elems(nqp::p6listitems(self));
my $eager = nqp::p6bool(nqp::istype($n, Whatever) || $n == $Inf);
Expand Down Expand Up @@ -388,24 +391,28 @@ my class List does Positional {
self.DUMP-OBJECT-ATTRS($attrs, :$indent-step, :%ctx, :$flags);
}

method keys(List:D:) {
method keys(List:) {
return unless self.DEFINITE;
(0..self.end).list;
}
method values(List:D:) {
method values(List:) {
return unless self.DEFINITE;
my Mu $rpa := nqp::clone(nqp::p6listitems(self));
nqp::push($rpa, $!nextiter) if $!nextiter.defined;
nqp::p6list($rpa, List, self.flattens);
}
method pairs(List:D:) {
method pairs(List:) {
return unless self.DEFINITE;
self.keys.map: {; $_ => self.at_pos($_) };
}
method kv(List:D:) {
method kv(List:) {
self.keys.map: { ($_, self.at_pos($_)) };
}

method reduce(List:D: &with) {
method reduce(List: &with) {
fail('can only reduce with arity 2')
unless &with.arity <= 2 <= &with.count;
return unless self.DEFINITE;
my Mu $val;
for self.keys {
if $_ == 0 {
Expand Down

0 comments on commit c3a58f9

Please sign in to comment.