📜 ⬆️ ⬇️

Perl6 - Classes

1. Features of working with variables and literals in Perl6
2. Perl6 - Variable operations, anonymous blocks
3. Perl6 - Conditional Operators, Loops
4. Perl6 - Working with Functions

The last few days I've been reading the section on working with objects in Perl6. Unfortunately, I still could not understand some of the points, and I hope that those who have already been able to understand them will prompt what the matter is. As before, all the described features will be accompanied by small experiments or examples to explain how it works, or how to use it.
Let's start:


In Perl6, there are two possible ways to declare a class:
-to make the entire file class description
class Name; has $.field; ... method Func() {...}; 

-declare a class with a construct
 class Name { has $.field; } 

As in C ++, you can specify only the name of the class, giving its description later:
 class Name {...}; my $var = Name.new; class Name {has $.elem}; 

If the last line is not, then an error will occur when compiling
It is also possible to do the following:
 my $className = class Name { has $.field is rw; } my $var1 = Name.new; my $var2 = $className.new; $var1.field = 10; $var2.field = 5; say $var1.field, ' ', $var2.field; 

As a result, we will see the line '10 5'
You can create an anonymous class using the construct
 my $anonClass = class :: {has $.field}; my $var = $anonClass.new; 

Already created variables can be used to create new variables:
 my $var1 = ClassName.new; my $var2 = $var1.new; 

However, the creation takes place without copying data.
')
Now more about what you can specify when announcing:
To specify a field, use the has keyword:
 class Name { has Int $.publicMember; has $!privateMember; has @.publicArray is rw; has %!privateHash; has $.a is rw; has $.b is rw = '  '; } my $v = Name.new; say $v.publicMember; # "Int()" #$v.publicMember = 10 - ,  readonly #say $v!privateMember -  $v.mas = 1, 2, 3; #say $v!privateHash -  $va = 'new value'; say $vb # "  " 

It is also worth noting that in the body of the method you can change private variables, even if it is readonly (However, I can’t say, this is how it was intended, or if the virtual machine is incomplete)

Methods for classes are indicated by the method keyword:
 class Name { has $!privateMember = 5; method GetPrivateMember() { return $!privateMember; } method SetPrivateMember($value) { $!privateMember = $value if $value > 0; } } my $var = Name.new; say $var.GetPrivateMember; $var.SetPrivateMember(10); $var.SetPrivateMember: 20; 


Methods can be declared private:
 method !PrivateMethod() { say 'Hello!'; } 

You can specify through which variable the object (invocant) will be available, in which the method is called:
 method Func($self: $param1, $param2) { $self.Func2($param1); } 

The variable name does not have to be $ self
 method Func($someName: $param1, $param2) { $someName!PrivateMethod($param1); } 

If this variable is not specified then the object itself will be available as 'self'
 method Func($param1, $param2) { self.PublicMethod($param1); self!PrivateMethod($param2); } 


To call in the body of a method of another method of this class, use the following construction
 self!PrivateMethod(); self.PublicMethod(); 

for example
 class Name { method !A() { say "!A"; } method A($s:) { $s!A(); } method B() { self!A; self.C; say "B"; } method C() { say "C"; } } 

It is possible to make calls self.A and self! A

To access the class fields in the body of the method, the same names are used as in the declaration:
 class Name { has $.a; has $!b; method PrintValues() { say $.a; say $!b; } } 

You can also write self.a but you cannot write self! B, since in this case, it will be implied to call the private method b, and not to access the variable b

If the class name when declaring is rw, then all the fields that will be contained in this class will be available for writing without specifying is rw for each field separately:
 class Name is rw { has $.a; has $.b; } 


You can also declare submethods in classes. Their difference from the usual methods is that the submethod will not be inherited by the child class.

Now about designers
You can specify which actions to perform when creating a new instance of a class:
 class Name { has $.arg1 is rw = 10; has $!arg2; submethod BUILD(:$namedArg1, :$namedArg2) { self.arg1 = $namedArg1 if $namedArg1>0; $!arg2 = $namedArg2; } } my $var = Name.new(:namedArg2(200), :namedArg1<Hello>); 

There is one thing that I do not understand: I had to write self.arg1 and not $ .arg1, because I got the error "Virtual call $ .a may not be used for partially constructed objects".
I cannot understand whether this is intended or whether this is just an incompletely worked out part. But in any case, this constructor works fine.

You can also specify a destructor that will be called automatically by the GarbageCollector.
 submethod DESTROY() { say 'DESTROY'; } 

But this time, the above inscription during the experiments, I could not see. I suspect that this part is also not completed yet.

In Perl6, inheritance is organized as follows:
 class Name {has $.a}; class Name2 is Name {has $.b}; my $var = Name2.new; say $var; #Name2.new(b => Any, a => Any) 


Perhaps multiple inheritance, as a result of which it may turn out that the names of functions or fields in classes will match:
 class Name { has $.a is rw = 10; has $.c is rw = 15; method A() {say "Name ", $.a;} } class Name2 { has $.b is rw = 20; has $.c is rw = 25; method A() {say "Name2 ", $.b;} } class Name3 is Name is Name2 { method A() { self.Name2::A(); say $.c; } } my $var = Name3.new; $var.a = 100; $var.b = 200; $var.A; 

In this case, two lines will be displayed:
 Name2 200 15 

If you do not override function A in the child class, then the Name :: A function will override the Name2 :: A function, also occurs with the $ .c variable
As I understand the string self.Name2 :: A (); does the Name2 :: A () method for the self object, but all my guesswork, how it works, is spoiled by the fact that an error is thrown to the name self.Name2, and you cannot write self. (& Name2 :: A) or something like this. I would be glad if someone from knowledgeable people will tell.

Of course, the features described here are only a part of what you can do with objects (for example, I didn’t even mention delegation, roles — analogs of interfaces in C ++), but for now I don’t want to delve into this topic so much, and continue exploring other Perl6 features. In the meantime, to start learning the language, the above will suffice.

Source: https://habr.com/ru/post/155571/


All Articles