2部 Perl言語仕様

リテラル

1.リテラルの概要

リテラルとは、プログラムのソースコード中に使用される定数のことです。つまり、okや 255 といった一般に使われる数字や文字列のことを指し、変数に代入したり出力したりすることができます。

リテラルの基礎

様々な種類のリテラルの代入
# 整数を代入
$x = 3;
# 実数を代入
$x = 3.141;
# 指数表記を代入
$x = 3e;
# 16進数を代入
$x = 0xffff;
# 8進数を代入
$x = 0377;
# 文字列を代入
$x = "abcdefg";

リテラルをコード中で表現するには、特定の書式を使います。リテラルの型として、ブール、整数、浮動小数点、文字列などがありますが、それらを表す書式は大きく分けて数値と文字列とがあります。

たとえば、文字列を表示する際は前後をダブルクォーテーション( " )やシングルクォーテーション( ' )で括る必要がありますが、数値の場合は、そのままでも問題ありません。

$x = "ok";    # 文字列リテラルを代入
$x = 255;    # 数値リテラルを代入

型キャスト

Perlでは、リテラルの型を厳密に区別しない方式をとっています。いくつかのプログラミング言語では、リテラルの型を指定して変数を宣言する必要があるものもありますが、Perlではリテラルの型を宣言する必要はありません。たとえば、Java や C言語のように型を厳しく管理する言語では、整数なら宣言時に int integer1;といったように宣言し、このように宣言した変数は整数しか代入することができません。また、そのようなプログラミング言語では、型キャストと呼ばれる、数値から文字列への明示的な変換などが必要になりますが、Perlでは自動的に行われます。

$x = 255 + "ok";    # 数値リテラルに文字列を連結
print $x;
>> 255ok

数値に文字列を連結するといった処理も、エラーではなく上記のような正常な処理がなされます。

論理値

リテラルには、『論理値』という特殊な型が用意されています。変数の値にどのようなリテラルが格納されていても、論理値として扱われるときは真(TRUE)偽(FALSE)の2種類の値として扱われます。

変数の値が数値の場合は 0 、文字列の場合は空文字が FLASE で、それ以外が TRUEとして扱われます。

論理値の使い方
$x = 0; # 値が 0 なので FALSE
$x = ""; # 値が空なので FALSE
$x = 1000; # 値が 0 以外なので TRUE
$x = "STRING"; # 値が空以外なので TRUE

論理値は、条件式などでよく利用されます。

論理値を使った条件分岐
$x = 0;
if ( $x ){
	print "TRUE の値です\n";
} else {
	print "FALSE の値です\n";
}
> FALSE の値です

このように、論理値は変数に値が入っているかを調べるときや、数式の計算が 0 かどうかを調べるのに便利です。

用語
論理値
論理値はTRUEかFALSEだけを扱います。値が数値の 0か空の文字列の場合は常にFALSE、それ以外はTRUEになります。

未定義値

リテラルには数値、文字列などのほかに、さらに『未定義』があります。未定義値は数値で評価されるときは 0、文字列の場合では空文字と解釈されます。宣言だけを済まし、まだ値を代入されていない変数は自動的にこの未定義値が設定されます。

未定義値を代入する-undef

変数に未定義値を代入するには、undef関数を使います。undef 関数は、既に定義された変数の定義を無効にします。関数の戻り値は常に未定義です。

undef $x;    # $x は未定義です

undef

未定義値かどうかを調べる-defined

未定義値を調べるために definedという関数が用意されています。

defined 関数は、引数が未定義か定義済みかをチェックし、定義済みの場合はTRUE、未定義の場合はFALSE を返します(変数が文字も数値も持たないNULLの状態のときが未定義です)。

# スカラ
print 1 if defined $x; # $x が定義された値であれば、1 を出力します。

defined

定数値

いくつかのプログラム言語には『定数』という変数があります。定数は最初に決めた値を最後まで記録し、値の変更を許可しません。Perlには型という概念がありませんが、ちょっとしたテクニックで定数を宣言することもできます。

定数を作成するには、下記のように『型グロブ』に参照を代入します。

定数の宣言
*MAX_BUF = 24
print $MAX_BUF, "\n";
> 1024

定数に値を代入しようとすると、エラーになります。

2.数値リテラル

『数値リテラル』は、整数や浮動小数点の表記法に従います。Perlの数値リテラルは整数や浮動小数点以外にも、それに8進数や16進数を扱うことができます。ここでは数値リテラルの記法と扱い方を紹介します。

数値リテラルの例

数値リテラルの例
数値リテラルの種類
整数 12345
8進数 0123
16進数 0x9F1F
浮動小数点 12.34
指数 .234E-2

8進数は 0 で始まり、16進数は 0x で始まります。指数記法で表される数値は、 Eの後に指数を表す正または負の数がつきます。

文字列と数値への変換では、先頭の 0x や 0 は認識されず常に10進数として扱われます。

整数と浮動小数点

多くのプログラム言語では、演算に関する規則が『整数』に関するものと『浮動小数点』に関するものがあります。ですが、Perlは型のない言語なので、整数と浮動小数点を区別しません。たとえば、整数同士で計算していたとしても、答えが浮動小数点になるものは浮動小数点として結果が返されます。

print 10 / 3;
> 3.33333333333333
整数
小数点を含まない数値です。
浮動小数点
小数点を含む数値です。

3.数値リテラルの変換方法

Perlでは、8進数を指定するときには、0123 のように先頭に 0をつけます。16進数の場合は、0x1AB のように先頭に 0xをつけます。10進数以外の数値を扱う場合は、10進数への変換方法と10進数からの変換方法を知っていると便利です。

16進数から10進数

16進数から10進数へ変換するには、hex関数を使います。

print hex( 0x1AB );
> 1063

hex

10進数から16進数

10進数から文字列表現の16進数へ変換するには、sprintf関数と書式指定子 %x を使います。

print sprintf ("%lx", 16), "\n";
> 10

sprintf

10進数から8進数

10進数から文字列表現の8進数変換するには、16進数の場合と同じように、sprintf関数とフォーマット指定子 %o を使います。

print sprintf( "%lo", 16 ), "\n";
> 20

8進数から10進数

8進数から10進数へ変換するには、oct関数を使います。

print oct 10, "\n";
> 8

oct

数演算 -integer

Perlは演算を浮動小数で行いますが、次のような指示で整数演算を行うようにとコンパイラに指示することができます。

use integer;

use integer を取り消すには次のようにします。

no integer;

4.文字列リテラル

文字列は文字を並べたものです。文字列リテラルの扱いは非常に簡単ですが、特殊文字や、日本語を使う際にいくつか注意点があります。

変数展開

『文字列リテラル』を扱うには、文字の並びをシングルクォーテーション( ' )か、ダブルクォーテーション( " )で囲みます。ダブルクォートで囲んだ中で変数を使うと、『変数展開』と呼ばれる変数の置き換えが行われ、変数の内容が返されます。シングルクォートの文字列では、後述するいくつかの例外を除き、特別な処理は行なわれません。

ダブルクォーテーション( " )の中で変数を使うと次のようになります。

$s = "simple";
print "It could all be so $s", "\n";
> It could all be so simple

シングルクォートでは次のように変数が展開されません。

print 'It could all be so $s', "\n";
> It could all be so $s

バッククォーテーション

バッククォーテーション( ` )を使うと、オペレーティングシステムへコマンドを渡すことができます。たとえばUNIX系OSの ls コマンドを使って次のようなことができます。

print `ls -l`;
> total 32
> drwxr-xr-x 3 jun jun 4096 Jul 16 20:52 folder/
> -rw-r--r-- 1 jun jun 1685 Jul 13 21:42 readme

文字列の連結

文字列リテラルの連結は文字列連結演算子のドット( . )を使います。

$x = "You might win some " . "but you just lost one";
print $x, "\n";
> You might win some but you just lost one

5.エスケープシーケンス

Perlには、『エスケープシーケンス』と呼ばれる、通常ディスプレイに表示されない文字や、紛らわしい文字を区別する為の特殊な文字が用意されています。たとえば、文字列の中で改行を表現したい場合は、「\n」という文字列を使います。

エスケープシーケンスの使用方法

エスケープシーケンスを含む文字列は、バックスラッシュによる解釈が行われるようにダブルクォーテーション(
" )で囲みます。シングルクォーテーション( ' )で囲むと \' と \\ を除いて解釈されません。

ダブルクォーテーション( " )に囲まれたエスケープシーケンスは正しく解釈されます。

print "\Uon sale!\E\n";
> ON SALE!

シングルクォーテーション( ' )に囲まれたエスケープシーケンスは解釈されません。

print '\Uon sale!\E\n';
> \Uon sale!\E\n
エスケープシーケンス一覧
エスケープシーケンス 説明
\t タブ
\n 改行(LF)
\r リターン(CR)
\f 改ページ
\b バックスペース
\a アラーム
\e エスケープ
\003 8進数
\x1b 16進数
\cC CTRL-C
\l 次の文字を小文字
\u 次の文字を大文字
\L \E が来るまで小文字
\U \E が来るまで大文字
\Q \E が来るまで英数字以外の文字にバックスラッシュ( / )を追加
\E \L、\U、\Qの終わり

上記以外にも、 Perl で予約されているダブルクォーテーション( " )、シングルクォーテーション( ' )、ダラー( $ )、アットマーク( @ )、パーセント( % )などの特殊文字をリテラルとして扱う場合は、前にバックスラッシュ( \ )を置くか、シングルクォーテーション( ' )で前後を囲み、変数などではないことを明確にする必要があります。

特殊文字のエスケープ一覧

特殊文字は、文字列以外として解釈される可能性のある記号です。たとえば、シングルクォートで囲んだ文字列の中でさらにシングルクォートを使いたい場合は、シングルクォートをエスケープして \' のように表現します。これで、文字列の終わりとしてのシングルクォートではなく、文字列として解釈されます。

特殊文字のエスケープ 出力結果
\" ダブルクォーテーション( " )のエスケープ
\' シングルクォーテーション( ' )のエスケープ
\$ ダラー( $ )のエスケープ
\\ エスケープのエスケープ
\@ アットマーク( @ )のエスケープ
\% パーセント( % )のエスケープ
\; セミコロン( ; )のエスケープ

6.クォートのような演算子

文字列リテラルを表現するには、クォートで文字列を挟みますが、クォート以外にもいくつかの演算子を使うことができます。クォートのような演算子には、クォートにはない機能を持っているものもあります。

クォートのような演算子の使用方法

クォートのような演算子の一覧
汎用記法 通常記法 意味 展開
q// '' リテラル 不可
qq// "" リテラル
qx// `` コマンド
qw//   単語リスト 不可
m// // パターンマッチ
s///   置換
tr///   変換 不可

展開可の構文は、ダラー( $ ) やアットマーク( @ )で始まる変数、エスケープシーケンスを展開します。バッククォートはダブルクォートの中では展開されません。また、シングルクォートがダブルクォートの中で使われても、変数の展開を妨げることはありません。

エスケープだらけになるのを避ける

文字列のなかで特殊文字が頻繁に登場すると、エスケープだらでとても読みにくくなります。これを避ける方法として、q//qq// 演算子が用意されています。

# 文章にダブルクォーテーション( " )がある場合はエスケープする
print "... they said, \"L.H, baby use your head\"";
>... they said, "L.H, baby use your head"
# ダブルクォーテーション( " )をエスケープする必要がない
print qq{... they said, "Lauryn, baby use your head"};
>... they said, "L.H, baby use your head"

q//
qq//

7.ヒアドキュメント

クォートは、シェルの『ヒアドキュメント』構文をもとにしています。ヒアドキュメントの記法は、<<の直後にヒアドキュメントの終了を表す識別子(終了文字列)を指定し、文章が終わった次の行に終了文字列をおきます。

$time = 3;
print <<EOF;
$time minits.This is it, Ground zero.
EOF
> 3 minits.This is it, Ground zero.

ヒアドキュメントのデフォルトの処理は、ダブルクォーテーション( " )で文字列を囲んだ場合と同じです。ヒアドキュメントの使い方で注意する点は、<<と識別子の間にスペースを入れないこと、そして、終了を示す行に終了文字列のみを単独で置くことです。

終了文字列をクォートで囲んだ場合には、そのクォートの種類(シングルクオート、ダブルクォート、バックスラッシュ)に従って処理されます。

$time = 3;
# シングルクォートを使った例
print <<'EOF';
$time minits.This is it, Ground zero.
EOF
> $time minits.This is it, Ground zero.
# 行を10回表示する
print << x 10;

8.特殊リテラル

__END__、__FILE__、 __LINE__、 __PACKAGE__などの特殊リテラルは、プログラムの論理的な終了を宣言するものであったり、プログラムの行数を保持していたりするリテラルです。

特殊リテラル

特殊リテラルの一覧
リテラル 解説

__END__
プログラムの論理的な終わり
__END__ 以降に続くテキストは全て無視され、コンパイルされない。ただし、DATA
ファイルハンドルで読み込むことができる。
__FILE__ 現在のファイル名
文字列中には展開されません。
__LINE__ 現在の行番号
文字列中には展開されません。
__PACKAGE__ 現在のパッケージ名
現在のパッケージがなければ未定義値です。 文字列中には展開されません。

プログラム内データの読み込み

Perl のプログラム最終行に、__END__を付けて、プログラム終了を明示的に宣言することができます。__END__以降の行は、コンパイル時に無視されるので、プログラムの説明などを記述しておくことができます。

#!/user/local/bin/perl
printf "Content-type: text/html\n\n";
....... # 処理
__END__
.......  # プログラム内データ 

このプログラム内データは DATAというハンドル名に割り当てられているので、次のようにすれば読み込むことができます。

@list = <DATA>

この機構を利用して、__END__ にプログラムのマニュアルを記述しておき、必要なときに DATAハンドルを使って出力することもできます。

#!/user/local/bin/perl
....  # 必要な処理
# なんらかしらの条件により、__END__ 以降の文章を出力
if ( ... ) {
	@list = <DATA>;
	print @list;
}
__END__
Document since "__END__"....
出力結果

Document since "__END__"....

関連記事