PerlIO

IO::scalarでIOのキャプチャ

STDIN/STDOUTを使うテスト IO::ScalarArray 標準入力の自動試験標準モジュールのIO::scalarでもIOキャプチャできますよ。 Tieによるモジュールと機能はほぼ同じです。 #!perl -w use strict; { my $content = "Hello, world\n"; open my $in, '<', \$content…

PerlIO実装メモ#3 PerlIOレイヤのデータ構造

PerlIOのデータ構造は以下の通り。 typedef struct _PerlIO PerlIOl; typedef struct _PerlIO_funcs PerlIO_funcs; typedef PerlIOl* PerlIO; struct _PerlIO { PerlIOl* next; /* Lower layer */ PerlIO_funcs* tab; /* Functions for this layer */ U32 fl…

PerlIOのメモリアロケーション

PerlIOのデータ構造の前に。 CレベルのPerlIO*については、PerlIOシステムがメモリ管理をしてくれる。そのメモリ管理を行うのがPerlIO_allocate()で、これが呼び出されると利用していないPerlIO*ポインタを探して返す。利用されていないPerlIO*ポインタがな…

open()の改良

Perlのopen()をマスターするのは大変だ。perldoc perlfuncのopenの項はすさまじい長さだし,perldoc perlopentutというopenのチュートリアルも,単なるチュートリアルなにものすごく長い。しかもPerlIOという機能のおかげでopen()そのものも自由に拡張できる…

PerlIO実装メモ#0 目次

デストラクタ PerlIOで出来ること PerlIOレイヤのデータ構造 PerlIOのメモリアロケーション PerlIOメソッド俯瞰 コンストラクタ/イニシャライザ PerlIO::scalarを読む 順番はいずれ整える。 9月になるとしばらく忙しくなるだろうから,8月中には書ければいい…

<>についての議論(p5p MLより)

perl5-porters[perl #2783]あたりから始まる<>についての議論を考えてみた。といってもp5pのスレッドはほとんど読んでないのでこの議論そのものがどういう流れになっているかは知らない(後で読む)。<>(引数を省略した行入力演算子)は@ARGVにファイル名が…

unread()のバグ

:scalar :scalarのunread()のバグについて,perlbugにレポートを送った。しかし添付ファイルを付け忘れた。 バグレポートは大分送り慣れてきたが,いつもファイルを添付するのを忘れてしまう。今回は,いつも添付し忘れるから本文にもファイル名を書いておこ…

PerlIO_unread()

PerlIO_unread()という,stdioのungetc()を拡張したようなPerlIO APIがある。 PerlIO APIのテストの為に,これをPerlから呼び出すモジュールを書いて,ついでにCPANにアップロードした。 しかし,これはちょっと思慮の足りない行為だったかもしれない。Perl…

PerlIOの実装メモ#2 PerlIOで出来ること

そもそもPerlIOで何が出来るのか。 その理解のために,標準PerlIO(組み込み+標準ライブラリ)とPerlIO::Utilなどのレイヤについて機能別に分類してみた*1 リソースアクセス系 PerlIOはI/Oのためのシステムだから,何らかのリソースにアクセスするレイヤが常…

openプラグマの落とし穴

openプラグマの挙動が異様だ。 以下のようなライブラリHoge.pmがあったとする。ライブラリファイルのエンコーディングはShift_JISとする。 package Hoge; sub hoge{ use Data::Dumper; my $hoge = "ほげ!"; printf "is_utf8: %d\n", utf8::is_utf8($hoge); …

*STDRRには不用意にレイヤを追加しないほうがいい

以下のコードは「done.」だけ出力して終了する*1。 #!perl -w use strict; binmode *STDERR, ':encoding(foo)'; print join(' ', PerlIO::get_layers(*STDERR)), "\n"; END{ print "done.\n"; } __END__ これはbinmode()がdieするためだが,本来なら,:encod…

PerlIO実装メモ#1 - デストラクタ

結論 PerlIOを実装するとき,リソースの開放はPopped()で行う。Close()を実装する必要はない。 解説 実装メモと称していきなりデストラクタの解説から入るのもどうかと思うが,PerlIOの実装にあたって突き当たる3番目の壁*1なので非常に重要である。 さて,P…

perlio.cの問題点のまとめ

perlio.c(v5.10.0)について,私が感じている問題をまとめてみた*1。明確なバグもいくつか見つけたが,それはきちんと報告することにする。したがってこのリストには載せていない。なお,以下でたびたび出てくるPerlIOBaseというのはレイヤに共通した機能を提…

PerlIO::code

Perlのopen()はファイル名に相当する引数がリファレンスだと特別扱いする。以下のようなことが出来るのはそのためだ。 my $scalar = 'foo'; open my $fh, '<', \$scalar; print <$fh>; # => "foo" これはスカラーリファレンスに対してPerlIO::scalarを自動的…

open()の実体

PerlIOが導入されてから,open()の実体はメソッドになっている。Cで実装されたPerlIOレイヤの仮想テーブルからメソッドを探索して,実際のopen()を行うのはそのPerlIOレイヤのopen()メソッドというわけだ。 open my $in, '

PerlIO::Util

PerlIOアーキテクチャを使ったアイデアをいくつか思いついたので具現化してみた。 http://search.cpan.org/dist/PerlIO-Util/ use PerlIO::Util; # push_layer()のため *STDERR->push_layer(tee => '>>foo.log'); *STDERR->push_layer(tee => \$logs); とか …