Declaring a variable belonging to a user-defined class in Perl 6
When you write my Int $a;
you will have a variable of type Int
, but without value, or even container. The concrete value of $a
will be (Int)
.
The same with my House $house;
- you will get (House)
value.
In your case you have to initialize array's elements by some House value. For example:
my @houses = House.new() xx 11;
@houses[10].area = 222;
I think you're missing the part that the compiler is doing some of the work for you. When you have a literal number, the parser recognizes it and constructs the right numeric object for it. There's a virtual and unseen Int.new()
that has already happened for you in rakudo/src/Perl6/Actions.nqp. It's at the NQP level but it's the same idea.
my House $a
does the same as my Int $a
. It puts a restriction on the values that you can put in it. If you look at the content of the variable, you will get the type object of that restriction.
There is a trick that you can use though, so you don't have to repeat the House
bit: my House $a .= new
, which is the equivalent of my House $a = House.new
.
To get back to your question: yes, you can do that with some trouble:
class House {
has $.area;
multi method area(House:U \SELF:) is raw {
(SELF = House.new).area
}
multi method area(House:D:) is raw {
$!area
}
}
my House @houses;
@houses[2].area = 42;
say @houses # [(House) (House) House.new(area => 42)]
We create two candidates for the accessor method: one taking an undefined type object, and the other an instantiated object. The first one modifies its invocant (assuming it to be a container that can be set), then calls the instantiated version of the method. I'm leaving this as an exercise to the reader to turn this into an Attribute
trait.