In addition to lizmat's excellent answer, it's probably relevant to explain what's going on here.
When you say my $foo
, you're effectively saying my Any $foo
.1 And when you say my @foo
, you're implicitly saying something closer to my Any @foo
which is the same as my Array[Any] $foo
(but in a positional container). That lets you put anything into the array, because it's typed, well, as Any
.
When you access an object that's undefined, it returns an undefined value — but that value is still typed. It just happens that by default, the type is Any
. We could, however, change some things and it would probably become clearer:
my Str $foo;
say $foo; # a Str that's undefined, so '(Str)';
my $bar; # implicitly typed Any
say $bar; # an Any that's undefined, so '(Any)';
my Int @foo = 0, 1, 2;
say @foo[0]; # an Int defined as 0, so '0'
say @foo[1]; # an Int defined as 1, so '1'
say @foo[3]; # an Int that's undefined, so '(Int)'
As lizmat pointed out in her answer, (Type)
is the default representation of the .gist
method, which is used by .say
, for undefined values.2
The reason that they don't return Nil
is because by definition, Nil
returns Nil
for every method that's called upon it (with a few exceptions like Bool
where it returns False
) — it's sort of like Objective-C's nil
. But an undefined type object still has uses: for instance, you can still call methods on it, as long as they don't access attributes. There are some times where that can be a very useful property, and it's what actually enables you to do something like:
my Foo $foo .= new;
Which is syntactical sugar for
my Foo $foo;
$foo = $foo.new;
$foo
is a an undefined type object, so we actually still call Foo.new
.
- As raiph rightly points out in the comments, I should have noted this isn't exactly what's going on, but from an end-user perspective, is close enough and much less complicated.
- One can always override this, and I've done that for some of my classes that have names suspiciously close to or identical to builtins that add a clear prefix so I don't get them mixed up.