class Nil
class Nil is Cool { }
The value Nil
may be used to fill a spot where a value would normally
go, and in so doing, explicitly indicate that no value is present. It
may also be used as a cheaper and less explosive alternative to a
Failure. (In fact, class Failure is derived from Nil
,
so smartmatching Nil
will also match Failure.)
The class Nil
is the same exact thing as its only possible value, Nil
.
say Nil === Nil.new; # OUTPUT: Ā«Trueā¤Ā»
Along with Failure, Nil
and its subclasses may always be returned from a
routine even when the routine specifies a particular return type. It may also
be returned regardless of the definedness of the return type, however, Nil
is considered undefined for all other purposes.
sub a( --> Int:D ) { return Nil }
a().say; # OUTPUT: Ā«Nilā¤Ā»
Nil
is what is returned from empty routines or closure, or routines
that use a bare return
statement.
sub a { }; a().say; # OUTPUT: Ā«Nilā¤Ā»
sub b { return }; b().say; # OUTPUT: Ā«Nilā¤Ā»
say (if 1 { }); # OUTPUT: Ā«Nilā¤Ā»
{ ; }().say; # OUTPUT: Ā«Nilā¤Ā»
say EVAL ""; # OUTPUT: Ā«Nilā¤Ā»
In a list, Nil
takes the space of one value. Iterating Nil
behaves like iteration of any non-iterable value, producing a sequence
of one Nil
. (When you need the other meaning, the special value
Empty is available to take no spaces when inserted into
list, and to return no values when iterated.)
(1, Nil, 3).elems.say; # OUTPUT: Ā«3ā¤Ā»
(for Nil { $_ }).raku.say; # OUTPUT: Ā«(Nil,)ā¤Ā»
Any method call on Nil
of a method that does not exist,
and consequently, any subscripting operation, will succeed and return
Nil
.
say Nil.ITotallyJustMadeThisUp; # OUTPUT: Ā«Nilā¤Ā»
say (Nil)[100]; # OUTPUT: Ā«Nilā¤Ā»
say (Nil){100}; # OUTPUT: Ā«Nilā¤Ā»
When assigned to a container, the Nil
value (but not any subclass of
Nil
) will attempt to revert the container to its default value; if no
such default is declared, Raku assumes Any.
Since a hash assignment expects two elements, use Empty
not Nil
, e.g.
my %h = 'a'..'b' Z=> 1..*;
# stuff happens
%h = Empty; # %h = Nil will generate an error
However, if the container
type is constrained with :D
, assigning Nil
to it will immediately throw
an exception. (In contrast, an instantiated Failure matches :D
because it's a definite value, but will fail to match the actual nominal
type unless it happens to be a parent class of Failure.) Native types can
not have default values nor hold a type object. Assigning Nil
to a native
type container will fail with a runtime error.
my Int $x = 42;
$x = Nil;
$x.say; # OUTPUT: Ā«(Int)ā¤Ā»
sub f( --> Int:D ){ Nil }; # this definedness constraint is ignored
my Int:D $i = f; # this definedness constraint is not ignored, so throws
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: Ā«X::TypeCheck::Assignment: Type check failed in assignment to $y; expected Int but got Any (Any)Ā»
sub g( --> Int:D ){ fail "oops" }; # this definedness constraint is ignored
my Any:D $h = g; # failure object matches Any:D, so is assigned
but
my Int:D $j = g;
# It will throw both exceptions:
# Earlier failure:
# oops
# in sub g at <unknown file> line 1
# in block <unit> at <unknown file> line 1
#
# Final error:
# Type check failed in assignment to $j; expected Int:D but got Failure (Failure.new(exception...)
# in block <unit> at <unknown file> line 1
Because an untyped variable is type Any, assigning a Nil
to one
will result in an (Any) type object.
my $x = Nil;
$x.say; # OUTPUT: Ā«(Any)ā¤Ā»
my Int $y = $x; # will throw an exception
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: Ā«X::TypeCheck::Assignment: Type check failed in assignment to $y; expected Int but got Any (Any)ā¤Ā»
If you are looking for a variable which transforms objects into type
objects when said variable appears on the right-hand side, you can
type the container as Nil
.
my Nil $x;
my Str $s = $x;
$s.say; # OUTPUT: Ā«(Str)ā¤Ā»
There is an important exception to this transforms-into-type-object rule:
assigning Nil
to a variable which has a default will restore that default.
my Int $x is default(42) = -1;
my $y = 1;
for $x, $y -> $val is rw { $val = Nil unless $val > 0 }
$x.say; # OUTPUT: Ā«42ā¤Ā»
Methods such as BIND-POS
, ASSIGN-KEY
, ASSIGN-POS
will die;
BIND-KEY
will produce a failure with an X::Bind exception in it, and
STORE
will produce an X::Assignment::RO exception.
Methods
method append
method append(*@)
Warns the user that they tried to append onto a Nil
(or derived type object).
method gist
method gist(--> Str:D)
Returns "Nil"
.
method Str
method Str()
Warns the user that they tried to stringify a Nil
.
method new
method new(*@)
Returns Nil
method prepend
method prepend(*@)
Warns the user that they tried to prepend onto a Nil
or derived type object.
method push
method push(*@)
Warns the user that they tried to push onto a Nil
or derived type object.
method unshift
method unshift(*@)
Warns the user that they tried to unshift onto a Nil
or derived type object.
method ords
Returns an empty Seq, but will also issue a warning depending on the
context it's used (for instance, a warning about using it in string context
if used with say
).
method chrs
Will return \0
, and also throw a warning.
method FALLBACK
method FALLBACK(| --> Nil) {}
The fallback method
takes any arguments and always returns a Nil
.
method Numeric
method Numeric()
Warns the user that they tried to numify a Nil
.