Akata Works

東京エンジニア。主にRuby,Go,たまにAWSとiOS。ゲーム音楽が好きです。連絡はTwitterかakata.onen@gmail.comまで

Perlの文字列の扱い方・・其の壱

いい加減に理解しておこうと思って、Perlの文字列の扱い方についてまとめました。長いので2回に分けたいと思います。あと、ちょっと覚書みたいになってます(文章って難しい・・)

簡単に概要と背景ですが、

Perlのバージョン5.8以降は内部文字列をutf8として扱うため、マルチバイト文字列が使用することができるようになりました。 そのとき、下位互換性を保つため、utf8フラグが付いている文字列を内部文字列とし、それ以外を外部文字列としました。

内部文字列:utf8フラグあり
外部文字列:utf8フラグなし

こんな感じだと思います。

ここで、ソースコード内に定義された文字列リテラルが内部文字列か外部文字列かを明示するプラグマについて紹介します。

これには"use utf8"プラグマと"use bytes"プラグマがあります。

"use utf8"プラグマはレキシカルスコープ内の文字列リテラルを内部文字列として扱い、"use bytes"プラグマは外部文字列として扱います。

以下のソースコードの実行結果が分かりやすいと思います。

use strict;
use warnings;

{
  use utf8;

  my $string = 'ほげ';

  print 'is utf-8: ' . ( utf8::is_utf8( $string ) ? 'true' : 'false' ) . $/;
  print 'lengths : ' . length( $string ) . $/;
  print 'string  :' . $string . $/;
}

{
  use bytes;

  my $string = 'ほげ';

  print 'is utf-8: ' . ( utf8::is_utf8( $string ) ? 'true' : 'false' ) . $/;
  print 'lengths : ' . length( $string ) . $/;
  print 'string  :' . $string . $/;
}

これを実行するとこうなります。

is utf-8: true
lengths : 2
Wide character in print at encode.pl line 64.
string  :ほげ
is utf-8: false
lengths : 6
string  :ほげ

前者の"ほげ"は内部文字列として扱われ、6バイトで2文字の文字列の長さが2であると解釈されていて、後者の"ほげ"は外部文字列として扱われ、6バイトで2文字の文字列の長さが6であると解釈されています。

なんで6バイトなのかというと、uft8における日本語が1文字で3バイトだからです。

ちなみにutf8::is_utf8関数はutf8フラグが付いているかを表す関数で、"Wide character in print at"という警告は内部文字列を出力したときに発生します。気になる方は次回で紹介するencode関数を使うといいです。

このようにPerlにはutf8フラグが付いているかで変化する処理があるため注意が必要です。デメリットもあまりないため、よく分からない人はなるべくutf8フラグを付けておくといいと思います。

ちょっと一息( ゚ ρ ゚ )ボーーーー(次回に続く)