次へ 目次へ 佐々木将人の個人ページへ
1 ファイル全部を読み込むけど何もしないで書き出す基本のフィルタ
……C言語を筆頭にプログラムを書いて最初にコンピューターにさせることは,最近では「Hello, world!」と出力させることが多いのですが,本稿では違うことをさせます。
私が某所でコンピューターについて初心者に向けて教えた際,コンピューターの本質は「何かのデータを与えると,それを元に何かのデータを返すこと」だと教えました。
後にとあるPerlの教科書を見たら,同じような指摘をしていて,これを具体的に実現するために,指定されたファイル全部を読み込むけど何もしないで全部書き出すプログラムを提示し,その種のプログラムを「フィルタ」と呼んでいました。
本稿でもこのフィルタをまず書くことにします。
Perl(参考)
#! /usr/local/bin/perl
use utf8;
use Encode;
open (IN, "in.txt");
open (OUT, ">out.txt");
while ( $_ = ) {
$_ = Encode::decode('UTF-8', $_);
&process1 ;
print OUT Encode::encode('UTF-8', $_);
}
close (IN);
close (OUT);
sub process1 {
return;
}
process1サブルーチンの中に処理したい内容を書けばいいことになります。
ちなみにこれは日本語を扱う時のものなので,ラテン文字だけを扱う場合には,もっと簡潔なコードで足ります。標準入出力を使う場合にも簡潔なコードになります。(標準入力はSTDINです。標準出力はSTDOUTですが,printでSTDOUTを省略することができます。)
Lisp
Erlang
perlでは,この基本のフィルタについては,入力については標準入力を,出力については標準出力を,それぞれ使用することにし,UNIXの機能であるリダイレクトを使って標準入出力を切り替えて使用することにしています。
それでErlangについてもそうしようと思って調べてみたのですが……。
Erlangの解説書では標準入出力の説明がないかきわめて薄い状況でした。
どうしたものかと悩んでいるうちに,はたと気がついたのです。
……リダイレクトというOSの機能に頼らずに,Erlangの中で書いてしまえばいいやん……。
そこでできたのが下記のプログラムです。
filter関数なのですが,入力するファイル名を(""で囲んだ上で)第1引数InFileに,出力するファイル名を第2引数OutFileに指定します。
そうするとInFileの内容をInBufferで受け取り,それをprocess関数に渡して,その結果をOutBufferで受け取り,それをOutFileに書き出します。
もっとも下記のコードではprocess関数では何も処理せず,与えられたデータをそのまま返すだけです。
何かをさせたければこのprocess関数で具体的に書いていくことになります。
-module(calbasis).
-export([filter/2]).
filter(InFile, OutFile) ->
{_, InBuffer} = file:read_file(InFile),
OutBuffer = process(InBuffer),
file:write_file(OutFile, OutBuffer).
process(X) ->
X.
LFE
(2023.9.7. 初版)
(2026.2.2. 最終改訂)
次へ 目次へ 佐々木将人の個人ページへ