3日目 - ファイル操作

この記事は”Perl6 Advent Calendar”エスパー和訳したものです。大意は合っていると思われるものの、内容は保証しません。


<原文>


3日目 - ファイル操作 (原文/Moritz)

Day 3 – File operations
By Moritz

ディレクト

Directories

(Perl5の)opendirなどとは違い、Perl6では指定したディレクトリ(デフォルトではカレントディレクトリ)に含まれるファイルのリストを返すdir関数があるだけです。ひとかけらのコードが、千もの言葉を話すのです(sp,e 結果は読みやすいように折り返されています)。

Instead of opendir and friends, in Perl 6 there is a single dir subroutine, returning a list of the files in a specified directory, defaulting to the current directory. A piece of code speaks a thousand words (sp,e result lines are line-wrapped for better readability):

    # in the Rakudo source directory
    > dir
    build parrot_install Makefile VERSION parrot docs Configure.pl
    README dynext t src tools CREDITS LICENSE Test.pm
    > dir 't'
    00-parrot 02-embed spec harness 01-sanity pmc spectest.data

dir関数はtestという名前付きオプション引数を持っており、結果をgrepするのに使います。

dir has also an optional named parameter test, used to grep the results

    > dir 'src/core', test => any(/^C/, /^P/)
    Parcel.pm Cool.pm Parameter.pm Code.pm Complex.pm
    CallFrame.pm Positional.pm Capture.pm Pair.pm Cool-num.pm Callable.pm Cool-str.pm

ディレクトリはmkdir関数を使ってmkdir('foo')のように作成します。

Directories are created with mkdir, as in mkdir('foo')

ファイル

Files

Perl6で最も簡単にファイルを読むにはslurp関数を使います。slurp関数はファイルの中身をStringとして返します。

The easiest way to read a file in Perl 6 is using slurp. slurp returns the contents of a file, as a String,

    > slurp 'VERSION'
    2010.11

もちろん古き良きファイルハンドルを使った方法も可能です。

The good, old way of using filehandles is of course still available

    > my $fh = open 'CREDITS'
    IO()<0x1105a068>
    > $fh.getc # reads a single character
    =
    > $fh.get # reads a single line
    pod
    > $fh.close; $fh = open 'new', :w # open for writing
    IO()<0x10f3e704>
    > $fh.print('foo')
    Bool::True
    > $fh.say('bar')
    Bool::True
    > $fh.close; say slurp('new')
    foobar

ファイルテスト

File tests

ファイルの存在や種類をテストするにはスマートマッチング(~~)を用います。こんな風に:

Testing the existence and types of files is done with smartmatching (~~). Again, the code:

    > 'LICENSE'.IO ~~ :e # does the file exist?
    Bool::True
    > 'LICENSE'.IO ~~ :d # is it a directory?
    Bool::False
    > 'LICENSE'.IO ~~ :f # a file then?
    Bool::True

とても簡単です。

Easy peasy.

  • File::Find

File::Find

普通の方法で物足りない時は、モジュールが便利です。File::Find(File::Toolsパッケージに含まれています)はディレクトリツリーを横断して、欲しいファイルを探し出して見つかったファイルの遅延リストを生成してくれます。File::FindはRakudo Starに付属していますし、あなたが素のRakudoを使っているならneutro(訳注:Simple Module Installer 詳しくはここを参照のこと)を使って簡単にインストールすることができます。

When the standard features are not enough, modules come in handy. File::Find (available in the File::Tools package) traverses the directory tree looking for the files you need, and generates a lazy lists of the found ones. File::Find comes shipped with Rakudo Star, and can be easily installed with neutro if you have just a bare Rakudo.

使い方の例ですか?分かりました。find(:dir, :type, :name(/foo/))はt/dir1という名前のディレクトリの中にあるファイルの内、/foo/という正規表現にマッチしたファイルの遅延リストを返します。気をつけないといけないことは、このリストは単なる文字列ではないということです:そのオブジェクトは(文字列コンテキストでは)フルパスを文字列化したものになりますが、単なる文字列だけでなく自分自身のファイル名(name)と、所属しているディレクトリ(dir)へのアクセサも提供します(訳注:Rakudo Star 2010.11では未実装。単なる文字列が返ります)。更に詳しい情報についてはドキュメントを参照してください。

Example usage? Sure. find(:dir, :type, :name(/foo/)) will generate a lazy list of files (and files only) in a directory named t/dir1 and with a name matching the regex /foo/. Notice how the elements of a list are not just plain strings: they’re objects which strinigify to the full path, but also provide accessors for the directory they’re in (dir) and the filename itself (name). For more info please refer to the documentation.

便利なイディオム

Useful idioms

新しいファイルを作る

Creating a new file

    open('new', :w).close
"無名"ファイルハンドル

"Anonymous" filehandle

    given open('foo', :w) {
        .say('Hello, world!');
        .close
    }