2007-08-03

やっぱ Perl しんどい

Perl 5.6 以降の Unicode 周りの話は華麗にスルーしてきたんだけど、あらためて昔のスクリプトをどうにかしようと思い、久々に Perl を触って悪戦苦闘。まずデータ構造の扱いにくさに泣きそうになる。ついで日本語。なんか Unicode がどうのこうでやたらといろんな方法がある。無理。こういうとき Perl の TMTOWTDI は本当に腹立たしい。どのやり方でもエレガントにできない言い訳じゃないのかと。

とりあえず設定を全部 YAML に逃がして、最終的に Perl でないもので動くように(!)持って行きたいがための作業なので、面倒なところはやはりスルーしつついくのがベストのような気がして来た。幸いこれ、日本語を直接読み書きしなきゃいけないものじゃないしな。

結局日本語周りをまとめた

例によって嘘、大げさ、紛らわしい場合はツッコミぷりーず。

基本

  • 5.8 以降では Perl は内部的に文字列を UTF-8 で扱うものとする
  • Perl 的に認められた文字列には UTF-8 フラグがつく
  • UTF-8 フラグのついていないものでも人間が文字列として認識するのは自由

use utf8;

コードが UTF-8 で書かれていることを宣言する。もしかすっと将来的にはこれがデフォルトになるのかも。

マルチバイト文字列を正しくマルチバイト文字列として扱おうとしてくれるが、副作用としてマルチバイト文字を print したときに警告が出るようになる。

逆につけなくても今まで通り日本語をコード中に書くことはできる1。これをそのまま print することは可能。euc-jp だろうが utf-8 だろうが同じ手法が使える。もちろん Shift JIS のように地雷を踏みやすいエンコーディングを選ぶ際は自己責任で。ファイルの読み書きも従来通りに動かせます2

ただし、use utf83しておかないと、シリアライズ系のものが軒並み \xXX 形式になってしまい、コマンドラインでの作業効率はよろしくない。つけてもつけなくても同じ結果になるモジュールもあるが、最近の UTF-8 フラグを解釈してくれるモジュールを扱う場合はつけておいた方が少し幸せになれるかも4

use utf8 しておくことで他にも嬉しいケースはあるかもしれないんだけど、あんまり詳しく調べてません。正規表現マッチを日本語で書けるような気がする。

binmode STDOUT => ":utf8";

UTF-8 フラグのついたマルチバイト文字列を print するときに UTF-8 フラグを落としてくれるので、警告が出なくなる。use utf8 したときはこれ書いておかないとコマンドラインでの作業が邪魔くさくなる。

もちろん一つ一つ

Encode::encode()

して出すっつー酔狂な選択をしてもいいけど、そんなの面倒じゃん。

use encoding CHARSET;

Perl 5.8 で内部的には UTF-8 でイクっつーのは決まったんだけど、そんでもどうしてもコードを Shift JIS で書きたいやい、UTF-8 なんてやだいやだいという場合にしゃあなしで使うことを許されるもの。

use encoding "euc-jp";

って書いたら euc-jp で書いてあるコードでも UTF-8 で書かれているのと同じようにマルチバイトな文字列として扱ってくれて、なおかつ STDIN も STDOUT も euc-jp を期待して動いてくれる。

当然、UTF-8 フラグ周りの警告も出ない。use utf8; とは排他と考えるべし。(実際には使えるみたいだけど、「混ぜるな危険」が基本です。)

use open

スクリプトもデータも euc-jp なんだけど、もうターミナルは UTF-8 で統一したいし、他の UTF-8 前提で動いてるアプリと組み合わせたい、という場合は、コード中にマルチバイトなリテラルを書いてなければ、

use open IN => ":euc-jp";
use open OUT => ":utf8";
binmode STDOUT => ":utf8";

とすることでそれなりに対処できる。上の例では euc-jp の入力、UTF-8 な出力を期待して動く。

ターミナルだけの問題なら screen でも対応可能だけど、他のアプリと繋げたいという場合は open を使うと楽できると思う。

use Encode;

使ってないんでよく分からないけど、これは変換以外に気にするポイントはないのかな。

なんかねぇ、似たような単語でいろいろな機能が動くんで、ものすごく分かりにくいです。

参考

  1. Perl 5.8.8 で確認した。 

  2. 5.8.0 では暗黙のうちに UTF-8 フラグが立っちゃってぎゃっ!と言う人が続出したらしい。 

  3. あるいは use encoding 

  4. シリアライズは Data::Dumper よりも YAML の方がいいような気がしてきた。でもどっちを使ってもハッシュを与えたらリストと勘違いしちゃうのでハッシュリファレンスを与えなきゃダメっつー辺り、やはりいや〜な気分にさせてくれる。 

About

例によって個人のなんちゃらです

Recent Posts

Categories

Tool 日々 Web Biz Net Apple MS ことば News Unix howto Food PHP Movie Edu Community Book Security Text TV Perl Ruby Music Pdoc 生き方 RDoc ViewCVS CVS Rsync Disk Mail FreeBSD Cygwin PDF Photo Zebedee Debian OSX Comic Cron Sysadmin Font Analog iCal Sunbird DNS Linux Wiki Emacs Thunderbird Sitecopy Terminal Drawing tDiary AppleScript Life Money Omni PukiWiki Xen XREA Zsh Screen CASL Firefox Fink zsh haXe Ecmascript PATH_INFO SQLite PEAR Lighttpd FastCGI Subversion au prototype.js jsUnit Apache Trac Template Java Rhino Mochikit Feed Bloglines CSS del.icio.us SBS qwikWeb gettext Ajax JSDoc Rails HTML CHM EPWING NDTP EB IE CLI ck ThinkPad Toy WSH RFC readline rlwrap ImageMagick epeg Frenzy sysprep Ubuntu MeCab DTP ERD DBMS eclipse Eclipse Awk RD Diigo XAMPP RubyGems PHPDoc iCab DOM YAML Camino Geekmonkey w3m Scheme Gauche Lisp JSAN Google VMware DSL SLAX Safari Markdown Textile IRC Jabber Fastladder MacPorts LLSpirit CPAN Mozilla Twitter OpenFL Rswatch ITS NTP GUI Pragger Yapra XML Mobile Git Study JSON VirtualBox Samba Pear Growl Mercurial Rack Capistrano Rake Win RSS Mechanize Sitemaps Android JavaScript Python RTM OOo iPod Yahoo Unicode Github iTunes God SBM friendfeed Friendfeed HokuUn Sinatra TDD Test Project Evernote iPad Geohash Location Map Search Simplenote Image WebKit RSpec Phone CSV WiMAX USB Chrome RubyKaigi RubyKaigi2011 Space CoffeeScript Nokogiri Hpricot Rubygems jQuery Node GTD CI UX Design VCS Kanazawa.rb Kindle Amazon Agile Vagrant Chef Windows Composer Dotenv PaaS Itamae SaaS Docker Swagger Grape WebAPI Microservices OmniAuth HTTP 分析基盤 CDN Terraform IaaS HCL Webpack Vue.js BigQuery Middleman CMS AWS PNG Laravel Selenium OAuth OpenAPI GitHub UML GCP TypeScript SQL Hanami Document SVG AsciiDoc Pandoc DocBook Develop Jekyll macOS Node.js Vite Heroku Transformer AI Data Cloud Wasm