自前でglobのマッチング

30分プログラム、その415。自前でglobのマッチングをやってみた。
いきなり正規表現にチャレンジするのは大変そうだったので、まずは簡単そうなグロブから。それも使えるメタ文字は*だけの非常に単純なやつで。
本当は、グロブのマッチにはバックトラックが必要になるから、継続を使ってハッピーになろうと思っていたら、別に継続を使わないですんなり書けてしまった。

使い方

match('mizuno','mi*'); # => true
match('mizuno','m*o'); # => true
match('mizuno','m*z'); # => false

ソースコード

#! /usr/bin/perl
# -*- mode:perl; coding:utf-8 -*-
#
# myglob.pl -
#
# Copyright(C) 2008 by mzp
# Author: MIZUNO Hiroki / mzpppp at gmail dot com
# http://howdyworld.org
#
# Timestamp: 2008/11/16 22:35:54
#
# This program is free software; you can redistribute it and/or
# modify it under MIT Lincence.
#

use strict;
use warnings;
use Data::Dumper;

use constant {
    True => 1,
    False => 0
};

sub head_tail($){
    my ($str) = @_;
    split(//,$str,2)
}

sub match($$){
    my ($lhs,$rhs) = @_;

    if($lhs eq '' and $rhs eq ''){
	True;
    }elsif($lhs eq '' or $rhs eq ''){
	False;
    }else{
	my ($x,$xs) = head_tail $lhs;
	my ($y,$ys) = head_tail $rhs;
	if($y eq '*'){
	    &match($xs,$rhs) or
		&match($xs,$ys) or
		&match($lhs,$ys);
	}elsif($x eq $y){
	    &match($xs,$ys);
	}else{
	    False;
	}
    }
}

print Dumper(match('mizuno','mi*')); # => true
print Dumper(match('mizuno','m*o')); # => true
print Dumper(match('mizuno','m*z')); # => false