hideden.hatenablog.com

はてなぶろぐー。URLなげー。

CGI.pmを継承してメソッドを追加したりしてみる。

文字コードの変換とかが面倒なのでCGI.pmを継承して、自動で文字コード変換をしてくれるモジュールを作ってみた。

Perlで他のモジュールを継承するのは簡単。

package CGI_JP_conv;
use base qw(CGI);

sub new {
    my $class = shift;
    my $self  = $class->SUPER::new(@_);
    return $self;
}
1;

とすればCGIモジュールのすべてのメソッドが呼び出せる。ってことで、paramメソッドにJcodeでの文字コード変換を付けてみる。

package CGI_JP_conv;
use base qw(CGI);
use strict;
use Jcode;

sub new {
    my $class = shift;
    my $self  = $class->SUPER::new(@_);
    return $self;
}

sub set_code {
    my $self = shift;
    my $code = shift;
    
    my $jcode = Jcode->new();
    $self->{conv} = sub { return @_; };

    if    ( $code eq 'sjis' ){ $self->{conv} = sub { return $jcode->set(@_)->sjis; }; }
    elsif ( $code eq 'euc'  ){ $self->{conv} = sub { return $jcode->set(@_)->euc;  }; }
    elsif ( $code eq 'jis'  ){ $self->{conv} = sub { return $jcode->set(@_)->jis;  }; }
    elsif ( $code eq 'utf8' ){ $self->{conv} = sub { return $jcode->set(@_)->utf8; }; }
}

sub param {
    my $self = shift;
    return $self->SUPER::param(@_) unless( defined $self->{conv} );

    my @value = map { &{$self->{conv}}($_) } $self->SUPER::param(@_);
    return wantarray ? @value : $value[0];
}

1;

呼び出し側スクリプト

#!/usr/bin/perl
use lib './lib';
use strict;
use CGI_JP_conv;

my $q = new CGI_JP_conv;
$q->set_code('utf8');

print $q->header;
print $q->param('test');

とすれば、自動的にJcodeで変換してくれる。ちょっと楽。


my %params = $q->Vars;

は、tieされたハッシュが返ってきて、取り出し時のメソッドが

sub FETCH {
    return $_[0] if $_[1] eq 'CGI';
    return undef unless defined $_[0]->param($_[1]);
    return join("\0",$_[0]->param($_[1]));
}

のようにparamメソッドを呼ぶため、きちんと変換されるはずです。



このパラメータには数字しか入って欲しくない!っとか結構ありますよね。取得してから正規表現で削ってもいいですが、

sub paramdig {
    my $self = shift;
    my @value = map { $_ =~ s/[^0-9]//g; $_; } $self->SUPER::param(@_);
    return wantarray ? @value : $value[0];
}

とかを追加しておくと、楽だったりするかも。