3. 変数

Perl6の変数は、3種類に分けられます:スカラー、配列、ハッシュです。

シジル (ラテン語で「記号」の意味) とは、変数の前についてる変数の種類を示す文字のことです。

  • $ はスカラー

  • @ は配列

  • % はハッシュ

3.1. スカラー

スカラーには、一つの値、またはリファレンスが入ります。

#文字列
my $name = 'John Doe';
say $name;

#整数
my $age = 99;
say $age;

変数が保持している値の種類により、それ用のさまざまな演算を行うことができます。

文字列
my $name = 'John Doe';
say $name.uc;
say $name.chars;
say $name.flip;
JOHN DOE
8
eoD nhoJ
文字列に適用可能なメソッドすべての一覧は http://doc.perl6.org/type/Str(英語) を参照してください。
整数
my $age = 17;
say $age.is-prime;
True
整数に適用可能なメソッドすべての一覧は http://doc.perl6.org/type/Int(英語) を参照してください。
有理数
my $age = 2.3;
say $age.numerator;
say $age.denominator;
say $age.nude;
23
10
(23 10)
有理数に適用可能なメソッドすべての一覧は http://doc.perl6.org/type/Rat(英語) を参照してください。

3.2. 配列

配列とは、複数の値が含まれるリストです。

my @animals = ['camel','llama','owl'];
say @animals;

下の例のように、配列に対して多くの種類の演算ができます:

チルダ ~ で、文字列として連結できます。
スクリプト
my @animals = ['camel','vicuña','llama'];
say "The zoo contains " ~ @animals.elems ~ " animals";
say "The animals are: " ~ @animals;
say "I will adopt an owl for the zoo";
@animals.push("owl");
say "Now my zoo has: " ~ @animals;
say "The first animal we adopted was the " ~ @animals[0];
@animals.pop;
say "Unfortunately the owl got away and we're left with: " ~ @animals;
say "We're closing the zoo and keeping one animal only";
say "We're going to let go: " ~ @animals.splice(1,2) ~ " and keep the " ~ @animals;
出力
The zoo contains 3 animals
The animals are: camel vicuña llama
I will adopt an owl for the zoo
Now my zoo has: camel vicuña llama owl
The first animal we adopted was the camel
Unfortunately the owl got away and we're left with: camel vicuña llama
We're closing the zoo and keeping one animal only
We're going to let go: vicuña llama and keep the camel
解説

.elems は、配列内の要素数を返します。
.push() は、一つの要素を配列に追加します。
@animals[0] のように、位置を指定することで配列の特定の要素にアクセスできます。
.pop は、配列の最後の要素を取り除きます。
.splice(a,b) は、 a の位置から b 個の要素を取り除きます。

3.2.1. 固定長配列

普通の配列は次のように宣言されます:

my @array;

普通の配列は好きなだけの長さになることができます。これを自動拡張と言います。
この配列には値をいくらでも制限なく入れることができます。

しかし、それとは違った固定長の配列を作ることもできます。
固定長配列では、決められたサイズを超えてアクセスすることはできません。

固定長の配列を宣言する場合は、配列名につづいて角かっこの中で最大要素数を指定します:

my @array[3];

この配列は最大で3つの値を入れることができ、0から2のインデックスがつけられます。

my @array[3];
@array[0] = "first value";
@array[1] = "second value";
@array[2] = "third value";

この配列に4つ目の値を加えることはできません:

my @array[3];
@array[0] = "first value";
@array[1] = "second value";
@array[2] = "third value";
@array[3] = "fourth value";
Index 3 for dimension 1 out of range (must be 0..2)

3.2.2. 多次元配列

ここまで見てきた配列は1次元です。
うれしいことに、Perl6では多次元配列を使うことができます。

my @tbl[3;2];

この配列は2次元です。 第1次元は3つ、第2次元では2つまでの値をとることができます。

my @tbl[3;2];
@tbl[0;0] = 1;
@tbl[0;1] = "x";
@tbl[1;0] = 2;
@tbl[1;1] = "y";
@tbl[2;0] = 3;
@tbl[2;1] = "z";
say @tbl
配列の完全なリファレンスは http://doc.perl6.org/type/Array(英語) を参照してください。

3.3. ハッシュ

ハッシュとは、キー/値のペアが集まったものです。
my %capitals = ('UK','London','Germany','Berlin');
say %capitals;
ハッシュの中身はもっとわかりやすく書くことができます:
my %capitals = (UK => 'London', Germany => 'Berlin');
say %capitals;

ハッシュで使えるメソッドをいくつか紹介します:

スクリプト
my %capitals = (UK => 'London', Germany => 'Berlin');
%capitals.push: (France => 'Paris');
say %capitals.kv;
say %capitals.keys;
say %capitals.values;
say "The capital of France is: " ~ %capitals<France>;
出力
(France Paris Germany Berlin UK London)
(France Germany UK)
(Paris Berlin London)
The capital of France is: Paris
解説

.push: (key ⇒ 'Value') はキー/値のペアを追加します。
.kv は、すべてのキーと値のリストを返します。
.keys は、すべてのキーのリストを返します。
.values は、すべての値のリストを返します。
%hash<key> のように、キーを指定することでハッシュの特定の値にアクセスできます。

ハッシュの完全なリファレンスは http://doc.perl6.org/type/Hash(英語) を参照してください。

3.4. 型

ここまでの例では、変数に入っている値の型を特に気にしませんでした。

.WHAT は、変数に入っている値の型を返します。
my $var = 'Text';
say $var;
say $var.WHAT;

$var = 123;
say $var;
say $var.WHAT;

上の例では、 $var の値の型は、最初は (Str) で次に (Int) になります。

このようなプログラミングスタイルを動的型付けと呼びます。動的とは、変数はどんな型の値でも保持できるという意味です。

では次に、下の例を実行してみましょう:
変数名の前に Int があることに注意してください。

my Int $var = 'Text';
say $var;
say $var.WHAT;

この例は失敗してエラーメッセージを表示します: Type check failed in assignment to $var; expected Int but got Str

何が起こったのでしょう?わたしたちはあらかじめ、変数に入る値の型は (Int) だと指定しました。 それで、 (Str) を代入しようとしたら失敗したのです。

このプログラミングスタイルは静的型付けと呼ばれます。静的とは、変数の型は代入の前に指定され、変えることができないという意味です。

Perl6は、 漸進的型付け に分類されます: 静的型付け動的型付け もどちらでも使うことができます。

配列とハッシュも静的型付けできます:
my Int @array = 1,2,3;
say @array;
say @array.WHAT;

my Str @multilingual = "Hello","Salut","Hallo","您好","안녕하세요","こんにちは";
say @multilingual;
say @multilingual.WHAT;

my Str %capitals = (UK => 'London', Germany => 'Berlin');
say %capitals;
say %capitals.WHAT;

my Int %country-codes = (UK => 44, Germany => 49);
say %country-codes;
say %country-codes.WHAT;
よく使われる型のリストです:

最初の二つを使うことはほぼ絶対にないと思いますが、参考までに挙げておきます。

説明

結果

Mu

Perl6の型階層のトップ

Any

新しく作るクラスと、ほとんどのビルトインクラスのデフォルトの基底クラス

Cool

文字列と数値に相互変換して扱うことができる

my Cool $var = 31; say $var.flip; say $var * 2;

13 62

Str

文字列

my Str $var = "NEON"; say $var.flip;

NOEN

Int

整数(任意精度)

7 + 7

14

Rat

有理数(任意精度ではない)

0.1 + 0.2

0.3

Bool

真偽値

!True

False

3.5. イントロスペクション

イントロスペクションとは、例えば型のようなオブジェクトの属性情報を取得することです。
これまでの例では、 .WHAT を使って変数の型を取得していました。

my Int $var;
say $var.WHAT;    # (Int)
my $var2;
say $var2.WHAT;   # (Any)
$var2 = 1;
say $var2.WHAT;   # (Int)
$var2 = "Hello";
say $var2.WHAT;   # (Str)
$var2 = True;
say $var2.WHAT;   # (Bool)
$var2 = Nil;
say $var2.WHAT;   # (Any)

値を持っている変数の型は、その値の型とされます。
強く片付けされた値を持たない変数の型は、その宣言された型となります。
強く片付けされてない値を持たない変数の型は、 (Any) となります。
値をクリアしたい場合には、 Nil を代入します。

3.6. スコープ

変数は最初に使う前に、宣言しなければなりません。

Perl6にはいくつかの宣言子があります。これまでの例では my を使ってきました。

my $var=1;

my 宣言子は変数に レキシカル スコープにします。 言い換えれば、変数はそれが宣言されたのと同じブロック内でのみアクセスできます。

Perl6でのブロックとは、 { } で囲まれている範囲のことです。 ブロックに囲まれていない場合、その変数はPerlスクリプト全体で有効になります。

{
  my Str $var = 'Text';
  say $var; #アクセスできる
}
say $var; #アクセスできないので、エラーを返す

一つのmy変数は宣言されたブロックからしかアクセスできないので、他のブロックの変数に同じ名前を付けることができます。

{
  my Str $var = 'Text';
  say $var;
}
my Int $var = 123;
say $var;

3.7. 代入と束縛

前の例では、値を変数に 代入 しました。
代入 には = 演算子を使います。

my Int $var = 123;
say $var;

変数に代入した値は変更することができます:

代入
my Int $var = 123;
say $var;
$var = 999;
say $var;
出力
123
999

一方、変数に 束縛 された値は変更できません。
束縛 には := 演算子を使います。

束縛
my Int $var := 123;
say $var;
$var = 999;
say $var;
出力
123
Cannot assign to an immutable value
変数を他の変数に束縛することもできます:
my $a;
my $b;
$b := $a;
$a = 7;
say $b;
$b = 8;
say $a;
出力
7
8

変数の束縛は、例にあるように双方向のものです。
$a := $b$b := $a は同じことです。

変数についてさらに知るには、 http://doc.perl6.org/language/variables(英語) を参照してください。