Perl6 最速っぽい構文マスター

Perl6 の文法一覧です。 他の言語をある程度知っている方はこれを読めば Perl6 の基礎をマスターして Perl6 を書くことができるようになっているといいなー(私が)と思います。

基礎

バージョン指定

  use v6;

標準出力への出力

print 文も使えますが、

  print 'Hello, World!';    #=> Hello, World!%

サンプルコードでよく使われているのは say です。

  say 'Hello, World!';     # => Hello, World!

print と違って say は改行も出力してくれます。 Ruby でいう puts と同じです。

コメント

コメントは Perl5 と同じ # です。

  # すごいコメント (すごい)

Pod コメントも使えます:

  say "ここがコード!";

  =begin comment
  複数行の
  コメントを
      書く時に
         便利!!
  =end comment

  say "またコード!!";

変数の宣言

変数の宣言は多分 Perl5 とあんまり変わっていない気がします。

  # スカラー変数
  my $age;

  # 配列変数
  my @dinasours;

  # ハッシュ変数
  my %dinasours_by_prices;

スクリプトの実行

スクリプトを実行するにはプロンプトで次のように打ちます。 先頭のコマンドが perl6 になっていることに注意してください:

  % perl6 ./script.pl

出力結果をファイルに書き出すにはリダイレクトを使います:

  % perl6 ./script.pl > ./file.txt

コンパイルチェック

事前にコンパイルチェックを行う場合はプロンプトで次のように打ちます:

  % perl6 -c ./script.pl

デバッガの起動

デバッガの起動の仕方はわかりませんでした。 ヘルプを見ても -d が無かったので………。

数値

スカラ変数に数値を設定できます。 整数でも小数でも設定できます。 桁数が大きい場合は `_'(アンダーバー)を区切り文字として利用できます。

  my $hoge = 1;
  my $piyo = 1.2354;
  my $fuge = 100_000_000;

四則演算

除算の場合は小数で返ってくることに注意してください。

  $hoge = 1 + 1;
  $hoge = 1 - 1;
  $hoge = 1 * 2;
  $hoge = 1 / 2;

余りと商の求め方はこんな感じです。 商を求めるには普通の除算を行った後に Int メソッドを呼び出して整数部を取得します:

  # 余り
  $mod = 3 % 2;

  # 商
  $div = ( 3 / 2 ).Int;

インクリメントとデクリメント

  # インクリメント
  $i++;

  # デクリメント
  $i--;

文字列

文字列はシングルクォーテーションかダブルクォーテーションで囲みます。 ダブルクォーテーションの中では \t(タブ)や \n(改行) などの特殊文字を利用することができます。 また、ダブルクォーテーションで囲まれた文字列の中では変数展開を行うことができます。

  my $str1 = 'Hello';
  my $str2 = 'World!';

  # 変数展開(結果は Hello, World!)
  my $str3 = "$str1, $str2";

文字列操作

メソッドに参照するときの記号が -> から . になったので文字列同士の結合が ~ になったことに注意してください。

  # 文字列の結合
  my $join1 = 'aaa' ~ 'bbb';

  my $join2 = [ 'aaa', 'bbb', 'ccc' ].join( ', 'numerical-variable1.pl );

  # 文字列の分割
  my @record = 'aaa,bbb,ccc'.split( ',' );

  # 文字列の長さ
  my $length = 'abcdef'.chars;

  # 文字列の切り出し
  my $substr = 'hola!'.substr( 1, 3 );

  # 文字列の検索
  my $found = 'howdy!'.index( 'how' );

配列

配列変数の宣言と設定です。 配列変数は複数の値を設定することができる変数です。

  # 配列変数の宣言
  my @array;

  # 配列変数への配列値の設定
  @array = 1, 2, 3;

配列の要素の参照と設定

シジルの使い方は Perl5 よりわかりやすくなった気がする。

  # 要素の参照
  say @hoge[0];         # => 1
  say @hoge[1];         # => 2

  # 要素の代入
  @hoge[0] = 1 * 4;
  @hoge[1] = 2 * 5;

配列の要素数

配列の要素数を取得するには elems メソッドを呼び出します。

  my $hoge_length = @hoge.elems;

配列の操作

配列を操作するための操作はメソッドとして呼び出します。

  # 配列の先頭の要素を取得(@hoge の要素は変化なし)。
  my $first1 = @hoge.first;

  # 配列の先頭の要素を取り出す。
  my $first2 = @hoge.shift;

  # 配列の先頭に要素を追加。
  @hoge.unshift( 5 );

  # 配列の末尾の要素を取得する(@hoge の要素は変化なし)。
  my $last1 = @hoge.end;

  # 配列の末尾の要素を取り出す。
  my $last2 = @hoge.pop;

  # 配列の末尾に要素を追加。
  @hoge.push( 9 );

ハッシュ

ハッシュじゃなくてマップと呼称せよとおっしゃる向きもいるみたいですが、ハッシュです。 というか、マップを継承したものらしいです。

  my %piyo;

  %piyo = 
      a => 1,
      b => 2,
      c => 3;

ハッシュの要素の参照と設定

  # 要素の参照
  my $a = %piyo{'a'};
  my $b = %piyo{'b'};

  # 要素の設定
  %piyo{'a'} = 2 + 3;
  %piyo{'b'} = 3 + 4;

ハッシュのキーは文字列ならシングルクォーテーションやダブルクォーテーションで囲まなければならないようです。

ハッシュの操作

  # ハッシュの全てのキーを取得。
  my @keys = %piyo.keys;

  # ハッシュの全ての値を取得。
  my @values = %piyo.values;

  # ハッシュのキーの存在確認。
  say %piyo<a>:exists;        # => True

  # ハッシュのキーの削除。
  say %piyo<a>:delete;        # => 5

制御文

if 式

  my %hoge = a => 42;

  if ( %hoge<a>:exists ) {
      my $a = %hoge{'a'};

      say "a があったよ!! 中身は $a だった。";
  }

if .. else 式

  my %piyo = a => 42;

  if ( %piyo<b>:exists ) {
      my $b = %piyo{'b'};

      say "b があったよ!! 中身は $b だった。";
  } else {
      say "懸命に捜索しましたが、残念ながら b は見つかりませんでした。";
  }

if .. elsif ... 式

  my %fuge =
      a => 42
      b => 42;

  if ( %fuge<a>:exists ) {
      my $a = %fuge{'a'};

      say "a があったよ!! 中身は $a だった。";
  } elsif ( %fuge<b>:exists ) {
      my $b = %fuge{'b'};

      say "b があったよ!! 中身は $b だった。";
  } else {
      say "懸命に捜索しましたが、残念ながら a も b も見つかりませんでした。";
  }

unless 式

  my %hoge = a => 42;

  unless ( %hoge<b>:exists ) {
      say "懸命に捜索しましたが、残念ながら b は見つかりませんでした。";
  }

while 文?

  my $i = 0;

  while ( $i < 5 ) {
      # 処理
      say $i;

      ++ $i;
  }

until 文?

  my $i = 0;

  until ( $i >= 5 ) {
      # 処理
      say $i;

      ++ $i;
  }

for 文?

Ruby みたいな Range リテラルが使えます。

  for 0..5 {
      say $_ * 4;
  }

foreach みたいに配列とかハッシュの各要素を処理したいならこんな感じ:

  for @doga -> $that {
      say $that;
  }

比較演算子

Perl6 でも数値と文字列(数値以外)で比較演算子が分かれているようです。

数値比較演算子の一覧

  say $p == $q;     # $p と $q は等しい。
  say $p != $q;     # $p と $q は異なる。
  say $p <  $q;     # $p は $q より小さい。
  say $p <= $q;     # $p は $q 以下。
  say $p >  $q;     # $p は $q より大きい。
  say $p >= $q;     # $p は $q 以上。

文字列(数値以外)比較演算子の一覧

  say $s eq $q;     # $s と $q は等しい。
  say $s ne $q;     # $s と $q は異なる。
  say $s lt $q;     # $s は $q より小さい。
  say $s le $q;     # $s は $q 以下。
  say $s gt $q;     # $s は $q より大きい。
  say $s ge $q;     # $s は $q 以上。

サブルーチン

Perl6 でも関数のことをサブルーチンというんじゃないかなーという予想。 サブルーチンを作るには次のように書きます:

  sub sum($n, $m) {
      my $total = $n + $m;

      return $total;
  }

引数の型を指定することもできます:

  sub sum(Numeric $n, Numeric $m) {
      my $total = $n + $m;

      return $total;
  }

Perl6 でやっと明示的に引数を指定することができるようになりました。 また、引数の型も指定できるようになりました。

ファイル入出力

C 言語っぽい open でファイルハンドルというか、IO オブジェクトっぽいものを受け取ってあれこれします。 下記の場合はファイルの内容を全て読み込んで $contents という変数に渡しています。

  my $file-handle = open $file-name, :r;

  my $contents = $file-handle.slurp-rest;

  $file-handle.close;

その他にも様々な方法があります。

  $contents = "test-file.txt".IO.slurp;

  $contents = slurp "test-file.txt";

ファイルの読み込み

読み込むときはファイルの 1 行づつを読み取りたいでしょう。 こんな時は lines メソッドを使って for で処理してもいいですね。

  for 'great-huge.csv'.IO.lines -> $line {
      # 何か $line を使った処理
  }

もし何かの理由で今処理せずにどこかに置いておいて、他の何かを行ってから行ごとの処理を行いたい時だってあります。 この場合は lines メソッドが全ての行の配列を返すので一旦配列変数に設定しましょう。

  my @lines = 'great-huge.csv'.IO.lines;

  # 何か行ごとの処理を行う前にやる処理


  for @lines -> $line {
      # 何か $line を使った処理
  }

ファイルの書き込み

ファイルに文字列を書き込む場合は open の第二引数に :w を設定します。

  my $file-handle = open $file-name, :w;

  $file-handle.print "Hello, ";
  $file-handle.say "World!";

  $file-handle.close;

最後に

Gist の方に Org Mode で書いたのを置いておきました。
こっちが先に書かれて、Markdown になった後、はてなブログに投稿されました。

DL したのを Emacs で開いて C-c v t するとあら不思議! 多分実行できるサンプルコードが生成されますので実行してみてください。

参照