Perl6 - Operations on Variables, Anonymous Blocks

    1. Features of working with variables and literals in Perl6
    In a previous article I described the features of working with variables, and also touched on contexts. In this article, I want to share the results of my experiments and searches on the use of variables, and also briefly describe the features of anonymous code blocks.
    Let's get started


    In Perl6, you can specify the type of a variable when declaring.
    For instance:
    my Int $var;

    With this declaration, only a number can be assigned to the $ var variable. If you try to assign a string or another type to a variable, then no automatic type conversions will be performed - the script will be stopped with an error about type checking. The type can be any existing data type, even user classes.
    You can convert from the specified type to others without any special restrictions.
    With such a variable declaration, its initial value will be Int (), and this value cannot be used - this is due to the fact that the constructor does not automatically call, and the variable receives an undefined value of the specified type. To create a new instance of an object when declaring a variable, you can use the construct
    my SomeClass $x .= new(a,r,g,s);
    my $x = SomeClass.new(a,r,g,s);
    

    You can find out if a variable has any value using the defined method:
    my Int $x;
    say $x.defined;   #False
    


    Another way to specify the type is to construct
    my $x is Int;

    However, in the latest, at the moment (12.09), version of Rakudo-star, this method does not work yet.
    The following method of specifying the type is also possible:
    my Array of Array of Int @x;
    

    however, in (12.09) it also does not work, so I can not say anything about the features of this method.

    Let's move on to the main operations - naturally this list is not complete, but I will give a list of the main operations that we will use:
    • Operations with numbers:
      • Typical binary and unary operations
        These are operations +, -, *, /
        In addition to the above, you can use the operations of taking the remainder of division (%, mod), raising to a power (**), increment and decrement (++, -), taking the integer part from division (div)
      • Bitwise operations: Bitwise “AND” (+ &), bitwise “OR” (+ |), bitwise shift (+ <, +>), bitwise “XOR” (+ ^)
      • Comparison operations: ==,! =, <,>,> =, <=.

    • String operations:
      Bonding two lines
      ('a'~'b')

      Repeating a line n times
      ('a' x 10)

      Comparison of strings: Strings are equal (eq), unequal (ne), alphabetically, line 1 comes before line 2 (lt, before), later (gt, after), earlier or match (le), later or match (gt)
    • - Operations with a logical type:
      AND (? &), OR (? |), XOR (? ^), NOT (!)
    • -Using Junction ()
      Junction is a special type, for group comparison - if you write
      $a == any(1, 2, 3)

      then the condition will be satisfied if the variable $ a is equal to at least one of the listed values.
      Possible operators
      • any ( $a==1 or $a==2 or $a==3)
      • all ( $a==1 and $a==2 and $a==3)
      • one ($ a is equal to only one of the specified values),
      • none ($ a! = 1 and $ a! = 2 and $ a! = 3)

      -Determination of the maximum (max) or minimum (min) number
      $a = 10 min 4;
      $b = 20 max 99;

      When using strings as operands, the comparison is in alphabetical order.

      -Ternary operator
      $ifValue ?? "yes" !! "no"

      The first operand is converted to the Boolean type, and if its value is true, then the second operand is returned, otherwise the third.

      -Use of the meta-operator
      There is the possibility of applying a specific operation for each element of the array:
      @a = (1, 2, 3);
      @b = @a X* 2;   #Умножение каждого элемента массива на 2, и создание нового массива
      @c = @a X** 2;  #Возведение в квадрат каждого элемента массива и занесение результата в новый массив


      -Selection of all elements
      In order to perform an operation for all elements of the array, the >> operator >> construct is used
      @a = 1, 2, 3;
      @b = @a>>**>>2, 100, 500;

      In this expression, all elements of the @a array are squared, creating a new array, two numbers are added to the resulting array: 100 and 500
      As a result, the @b array contains (1, 4, 9, 100, 500)

      -The zip operator is
      used to pair items from two arrays:
      @a = (1, 2, 3);
      @b = (4, 5, 6);
      @c = @a Z @b;   #(1, 4, 2, 5, 3, 6)


      Abbreviated form of operator notation
      In order to add all the numbers you can use the notation [+]
      @a = 1, 2, 3;
      $a = [+] @a;

      The result is $ a = 1 + 2 + 3;

      Creating an alias
      You can create an alias for a variable that will be considered the second name of the variable. Variables point to the same area in memory, therefore changes through one variable name will be visible through the second variable name. Creating an alias is indicated as ': ='
      $a = 1;
      $b := $a;


      Creating an immutable variable
      To create an immutable variable, use the operator ':: =' for example
      my $a ::= "aaa";
      

      However, in the current version (12.09), such an announcement gives a compilation error.

      Getting a variable reference
      You can get a variable reference using '\':
      $a = 10;
      $b = \$a;




    Now about blocks:
    Blocks in Perl 6 can be used as data: individual blocks can be assigned to scalar variables and then executed:
    $b = 10;
    $a = { $b = 1; };
    $a();
    say $b;   # $b=1;

    When a block is called for execution, the result of the call is the last calculated value in this block. In this example, the calculated value is constant 1. Inside the blocks, the return statement cannot be used to end the operation of the block: it will complete the execution of the function in which the block is called.
    Blocks can be used as arguments in function calls:
    func($arg1, $arg2, { say 'this is a block'; });

    Variables can be declared inside blocks, or existing ones can be redefined: a block sets its scope of variables, and changes to variables declared inside a block do not affect variables of the same name outside this block.
    In the following code
    my $a = 'Начальное значение переменной';
    my $closure = { say $a; };
    {
        my $a = 'Измененное значение переменной';
        $closure();
    }

    the line 'Initial value of the variable' will be displayed, because when creating the $ closure variable, a variable declared in the global scope was used, and even after defining a variable with the same name $ a inside the block, the first one will be used.
    In the following code, the $ a local variable for the block will be used, even if it is no longer accessible from the place where it is visible.
    my $a = 'Начальное значение переменной';
    my $closure;
    {
        my $a = 'Измененное значение переменной';
        $closure = { say $a; };
    }
    $closure();

    Also popular now: