When I declare a variable, whose value belongs to a built-in class, I simply write
my Int $a;
But when I want to use a user-defined class, I have to use Classname.new
.
my class House {
has $.area is rw;
}
my $house1 = House.new;
$house1.area = 200;
say $house1.area;
So, my naïve question is, what's the reason of that difference? Why can't we simply write my House $house1
?
My ultimate goal is to use an array whose values are instances of a user-defined class. How can I do the following correctly?
my @houses ...;
@houses[10].area = 222;
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With