Permalink
Browse files

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 c3a58f998dd21535d986a8a42003c11fe7266f78
Showing with 29 additions and 17 deletions.
  1. +16 −12 src/core/EnumMap.pm
  2. +1 −0 src/core/Hash.pm
  3. +12 −5 src/core/List.pm
View
@@ -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) {
@@ -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)
@@ -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;
@@ -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;
@@ -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);
}
View
@@ -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(
View
@@ -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);
@@ -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 {

0 comments on commit c3a58f9

Please sign in to comment.