パイプラインパターンでテキスト処理

パイプラインパターンで、ちょっとだけ実用的な例を。
ログなんかをPerlRubyで処理して必要な部分を抜き出したりなんてことをよくやると思いますが、PerlRubyではファイルを開いて一行ずつ処理するのが超簡単です。パイプラインパターンを使えば、同様に簡単にできるので、実演してみました。
Mapに渡したdelegateで行番号をつけて、Takeで先頭10行だけ抜き出しています。


static void Main()
{
try
{
int lineCount = 0;

foreach ( string str in Take( 10, Map<string, string>( delegate( string s )
{ return ++lineCount + " : " + s; },
TextFileReader( "../../Program.cs" ) ) ) )
{
Console.WriteLine( str );
}
}
catch ( Exception e )
{
Console.WriteLine( e.Message );
}

Console.Read();
}

static IEnumerable<string> TextFileReader( string fileName )
{
using ( StreamReader sr = new StreamReader( fileName ) )
{
string line;
while ( ( line = sr.ReadLine() ) != null )
yield return line;
}
}

static IEnumerable<S> Map<T, S>( Converter<T, S> converter, IEnumerable<T> input )
{
foreach ( T var in input )
yield return converter( var );
}

static IEnumerable<T> Take<T>( int count, IEnumerable<T> input )
{
if ( 0 < count )
{
foreach ( T ele in input )
{
yield return ele;
count--;
if ( count <= 0 )
break;
}
}
}

わかりますかね?もうC#に見えないかもw
サンプルでは全部パイプラインにつないでいますが、無理に繋げず、foreachのループの中で処理してもいいですね。
フィルタかけたり、Mapで各行に何か処理したりといったあたりが楽にできます。

まぁ、ログ処理だとクイックハックできないコンパイル言語の出番は少ないですけど。