...

пятница, 16 августа 2013 г.

Perl6 — Работа с типами данных

До сих пор в статьях было лишь поверхностное упоминание о типах данных — объявление переменной определенного типа, либо указание результата операции, но все что мы могли, это лишь терпеть выходки компилятора — «хочу умру (die), захочу варнинг кину, или просто поменяю тип».

Собственно, для тех кто хочет почувствовать себя богом хоть как-то важным в управлении типами в своем же скрипте, добро пожаловать под кат.


Итак, допустим мы написали функцию, которая принимает в качестве параметров две переменные:



sub Func($a, $b) {...}


И нужно нам, чтобы функция отрабатывала всегда одним образом, но если вдруг будут переданы в качестве параметров дробное число и строка, или же наоборот, то выполнить другие действия.


Начнем с малого — узнаем какой у нас тип данных у каждой из переменной, для этого используем метод WHAT, который вернет type object — объект обозначающий тип данных (например для значения 10 будет возвращен объект "(Int)" ). Следует отметить, что возвращается именно объект, а не строка, и простое сравнение двух типов через, например, == или eq не подойдет. Для того чтобы сравнить полученный объект с типом мы воспользуемся оператором умного сравнения '~~':



sub Func($a, $b)
{
$condition = ( ($a.WHAT ~~ (Rat)) ?& ($b.WHAT ~~ (Str)) );
$condition ?|= ( ($a.WHAT ~~ (Str)) ?& ($b.WHAT ~~ (Rat)) );
if ($condition)
{
#`(SomeWork)
}
else
{
#`{AnotherWork}
}
}




(Rat) и (Str) являются type object'ами действительных чисел и строк соответственно.

Для тех кто уже подзабыл ?& — Логическое «И», ?| — Логическое «ИЛИ».

И так, мы научились определять тип значения переменной, и взависимости от него выполнять какие либо действия. Но давайте посмотрим, в каких именно случаях это делать необходимо:



my Int $a;
sub Func($p)
{
$a = $p;
}

Func(10);
Func("Test");




В нашем случае, скрипт умирает когда пытается переменной, которая может содержать только целые числа, присвоить строку.

Подкорректируем немного наш пример, и напишем следующее:



$a = +($p);




В результате мы так же словим ошибку, и скрипт умрет, а ошибка будет не про присваивание а про неправильный тип в числовом контексте, из чего мы сделаем вывод, что частные контексты лишь добавляют ограничений по типам, и что для ручного преобразованя типов нам нужно что-то другое.

Попытаемся использовать следующую конструкцию:



$a = Int($p);




Уже лучше, так как если мы передадим число типа (Rat), то оно будет преобразовано к типу (Int), но вот если мы передадим строку, то получим уже ошибку преобразования строки в число, а именно о том, что строка должна иметь вид числа в 10-ой системе счисления.

Пока что я нашел только один способ заставить скрипт работать дальше — отлов исключений. На мой взгляд это самое логичное действие, но об этом мы поговорим в следующих статьях

Также наш скрипт может умереть если функция попытается вернуть значение, несоответствующее описанию:



sub Func($p) of Int
{
return $p;
}
Func("test");




Так что в данном случае, тоже не помешало бы сделать проверку выходных значений.

На последок хочу сказать, что по моему мнению ограничения на типы хранимых данных может сильно помочь в описании «интерфейсов» функций, и дают некоторые плюсы типизированных языков программирования.

Надеюсь эта информация была полезной.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at fivefilters.org/content-only/faq.php#publishers. Five Filters recommends: 'You Say What You Like, Because They Like What You Say' - http://www.medialens.org/index.php/alerts/alert-archive/alerts-2013/731-you-say-what-you-like-because-they-like-what-you-say.html


Комментариев нет:

Отправить комментарий