Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring a variable belonging to a user-defined class in Perl 6

Tags:

raku

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;
like image 383
Eugene Barsky Avatar asked Nov 28 '17 09:11

Eugene Barsky


Video Answer


2 Answers

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.

like image 91
Elizabeth Mattijsen Avatar answered Sep 27 '22 16:09

Elizabeth Mattijsen


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.

like image 27
brian d foy Avatar answered Sep 27 '22 18:09

brian d foy