Perl

Posts filed under Perl

長月葵->Status()->Perl

Filed in Perl, prog

 てなわけで長月の Perl 力がどれぐらいなのか。
 最近マイブームの何とか判定をやった訳ではないので主観なんですが、とりあえず基準としては http://d.hatena.ne.jp/naoya/20050809/1123563794 で書かれている物を使います。
 レベル4: use strict はもう書き出したら自動書記するぐらいだけど use warnings なんてしてないなぁ。 -w スイッチじゃダメですか?w
 レベル6: CPAN はあまり使わないかなぁ。標準モジュールで足りる事も多いし。まあでも標準モジュールに欲しい物が無ければとりあえず CPAN 見に行くのはやるから○かなぁ。
 レベル7:オブジェクト指向で書くとかモジュール作るとかは CPAN あさる様になる前からやってますがね。なんか学習の順番も割と個人差あるはずだからこのレベル表割と違和感ある人多そう。
 レベル8: AUTOLOAD は知ってるけど使いこなすというかふと使おうと思うほどは習熟してないなぁ。CPAN にモジュール送ったりもしないし。初心者さんに教えたり CGI.pm 使って CGI 作ったりはするけどね。
 どうも当てはまりそうなのはここらまでかな? レベル8についてはちゃんと対応できてるとは思えないのでレベル7ぐらいかな。
 なんか割とやっと中の上ぐらいになったかなと思ってたのは大体あってたみたいです。
 なんだかんだで Perl 使いつづけて四年ですからそれぐらいにはなってても不思議じゃないですね。
 ここを見てる Perl 使いの皆さんは如何ほどでしょうか?

えーと、あれー? その後

Filed in Perl, prog

 なんかどうも糞いMIME エンコード済み文字列を持ってるらしい携帯メールのデータに付いてあれこれ調べてたんですが、 「なんか自力でやらなくても携帯メーカにデータ取り込むソフトあるらしいぞ」と言う事が判明。出来るからって調べる前に動く無計画っぷりが知れます。とりあえずはメーカホームページへ直行。
 しかし眺めてみてもSDカード経由での操作が用意されてない模様。糞い。仕方ないのでUSB経由でと思って携帯を買った時にブツが入ってた袋を探ってみてもケーブルなんぞない。うわ、別売ですか?
 結局自力でやる事に決定……orz
 さらに調べて回って結局解らないので RFC を読みに行く。最初からやっとけよって話なんですが英語読むのめんどくさいんです。日本語訳済みは訳が好みじゃないとか、どこまで正確か信じられないとかの問題で読むなら原版って人なんで。原版でも自分訳がアレなら結局同じとか原版書いた人が間違ってたらって話は棚に上げときます。
 それで RFC 2045 読んで 6.7.5 Soft Line Breaks 辺りが怪しげに見えたりしてやってみました。ソフト改行用の等価記号削除。見事に文字化け解消。それぐらい対応しといてくれ MIME::QuotedPrint ……orz
 むぅ、ライブラリの類は普通それなりにブラッシュアップしてある物と思い込んでたのが敗因ですね。疑ってごめんなさいPで始まる某社の担当の人m(_ _)m
 こんな事だから「これからはモジュールを信用しないで、むしろモジュールまで自作で行くべき!」とか車輪の再発明好きに言い訳を与えるんですよね┐(´ー`)┌

えーと、あれー?

Filed in Perl, prog

 以前書いたメールをうんちゃらのスクリプトなんですが。Perl で MIME::Base64 モジュールと MIME::QuotedPrint モジュール使って復号化してます。
 しかしなにやら文字化けなさるんですよね。んで元データ見てみたらなにやら微妙に不正なデータ。曖昧変換できたらまあいけるんだろうなって感じなんですが、MIME モジュールは割と厳密な変換をするようで化けます。
 これ何とかならないんですかね? オプションとかで曖昧変換出来たりとかしないんですかね?
 ああ、そう言えば use MIME::Explode; してる割に使ってないなw ヘッダの解析にせswitch 文でやっちゃってるよ'`,、(´∀`)'`,、

やっぱり間違えてた(´・ω・`)

Filed in Perl, prog

 なんかバージョンを変えたら解決しました。
 最初に試してた奴のバージョンは 1.99_06、今回のが 0.88。
 どうも新しいのは Perl 5.8.* で追加された Encode モジュールのラッパみたいで、一応 Jcode 0.88 相当のコードは含まれてる物の内部構造が大幅に変わってる模様。古いコードを Jcode::_Classic に押し込めたおかげでおかしな事になった様です。
 つーことで、同じような罠に引っかかってここにきた人、Jcode 0.* に差し替えましょう(´・ω・`)

むむ? 何かを間違えましたか?

Filed in Perl, prog

 ちょっと入用になって Jcode.pm の OpenLab の Jcode.pm プロジェクトページから以前DLしておいた物をインスコ。といってもコピるだけ。インスコ用のスクリプトついてないし(´・ω・`)
 コピー終了して既に組んであるスクリプトを実行してみると。

Undefined subroutine &Jcode::_Classic::euc_utf8 called at <Perlのパス>/lib/Jcode/_Classic.pm line 255

 と出る。はて? インスコ失敗してたのけ? 該当個所を見てみる。よくわからん。load_module 関数が関係してそうだけど、load_module 関数を眺めてみても解らず。デバッグ表示ではパッケージはちゃんと require されてるっぽいしなぁ。
 といった所でふと気付く。ああ、パッケージ名の修飾がないんだ。自作ライブラリだとちゃんとパッケージ化せずに内部で使う変数だけ $Hoge::variable_ とかして関数は require だけで呼べるようにしてたせいで勘違いしてた。
 てことでパッケージ名を補ってやれば通るかな? パッケージ名は load_module 関数が返してるから、後は関数名を付け足してシンボリック参照辺りで何とかなるな。ってなんでそんなニッチな機能だけはすぐに思い出せるんだ俺……orz
 であ実行( ・∀・)σぽちっとな

Can't use string ( snip ) as a subroutine ref while "strict refs" in use at <Perlのパス>/lib/Jcode/_Classic.pm line 256

 ……orz
 もう訳わかんないんで誰か似たような事例と解決策教えてくだちぃ……orz

スキン対応CGIのススメ

Filed in Perl, prog

 知り合いの日曜ぷるぐらまさんが「スキン対応CGIを計画中」とおっしゃって居たのでHTML::Templateモジュールを教えてさしあげました。
 で、ちょっと考えてみたんですが、自分も含めて作る立場から見て、スキン対応CGIの需要って高いんじゃないかと思うんですよ。
 使う側からしても面白いんですが、作る側から見るとUIとロジックの分離が出来るって事でお得なんですよね。本来アプリケーション構成の多層化って設計の基本なんですけど、CGIに於いては割と軽視されてると言うか、そう言う構成になっていないことも多いンじゃないかと思います。最近スタイルシートをいじってる所為か、見た目を変える為にソースをいじるのはナンセンスに感じるんですね。だからここ最近作ってるPerlCGIやPerlでHTMLを吐く類のプログラムではもっぱらHTML::Templateモジュールを使ってます。
 で、自分で便利だと感じる物は同じ事を考える人のために紹介しなきゃでしょと思ったので紹介してみようかと思います。
 まずはインストール、Perlのバージョンによっては入ってるかも知れませんが、うちのPerl環境 (ActivePerl 4.6.1) では入ってなかったのでCPANから落としました。ActivePerlを使ってる方ならPPMコマンドで適当に落として下さい。ppm install HTML-Templateでインストール出来ると思います。
 PPMコマンドの使い方はhttp://digit.que.ne.jp/work/index.cgi?Perl%A5%E2%A5%B8%A5%E5%A1%BC%A5%EB%2F%A5%A4%A5%F3%A5%B9%A5%C8%A1%BC%A5%EB(PPM)を見れば詳しく書いてあります。
 Windows + ActivePerl 以外の環境の方は適当に何とかして下さい。Linux何かだとRPMパッケージも用意してあったかと思います。
 インストールが済んだら取り説をざっと見てみましょう。perldocコマンドで取り説を読むことが出来ますが、文章が英語なので長月の様な英語だめぽな方はperldocJPプロジェクトで公開されている翻訳済みドキュメントを読みましょう。
 PerldocJP: http://perldocjp.sourceforge.jp/
 さて、取り説の説明に拠ると、HTML::Templateモジュールで読み込むテンプレートファイルは基本的にHTMLの様です。これなら簡単です。まずはHTMLで実現したいページを書いてみます。例として自作のHTMLジェネレータで使っているテンプレートを晒してみます。

<!DOCTYPE html
PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Language" content="ja">
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<meta name="GENERATOR" content="Aoiro HTML Generator 1.0">
<title><!--TMPL_VAR NAME="title"--></title>
<link rel="stylesheet" type="text/css" href="<!--TMPL_VAR ESCAPE=HTML NAME="file_dir"-->CSS/base.css">
</head>
<body>
<div id="base">
<div id="main">
<div id="logo">
<img src="<!--TMPL_VAR ESCAPE=HTML NAME="logo"-->">
</div><!--/div id="logo"-->
<div class="navi">
<ul class="navi">
<!--TMPL_LOOP NAME="navi"-->
<li class="navi"><!--TMPL_VAR NAME="navi_item"--></li>
<!--/TMPL_LOOP-->
</ul>
</div><!--/div class="navi"-->
<!--TMPL_VAR NAME="body"-->
</div><!--/div id="main"-->
<div id="menu">
<!--TMPL_LOOP NAME="menu_captions"-->
<ul>
<li class="caption"><!--TMPL_VAR NAME="menu_caption"--></li>
<!--TMPL_LOOP NAME="menu_items"--><li><!--TMPL_VAR NAME="menu_item"--></li>
<!--/TMPL_LOOP-->
</ul><!--/TMPL_LOOP-->
</div><!--/div id="menu"-->
</div><!--/div id="base"-->
<div id="Copyright">
<hr>
Copyright (C) 2002-2005 September Software,<br>
長月 葵<aoi_nagatsuki@nagatsuki-do.net><br>
All Rights Reserved.<br>
<font style="color: red">スパム防止の為@を全角にしています。</font><br>
<img src="<!--TMPL_VAR NAME="file_dir"-->image/banner.gif">
</div><!--/div id="Copyright"-->
</body>
</html>

 なにやらHTMLにないタグがいくつか出てきてますね。<!--TMPL_VAR NAME="hoge"-->とか<!--TMPL_LOOP NAME="piyo"-->とか。これがHTML::Templateモジュール用テンプレートの制御タグです。詳しくはPODを読んで貰うとして、頻繁に使うであろう<!--TMPL_VAR NAME="hoge"-->と<!--TMPL_LOOP NAME="piyo"-->~<!--/TMPL_LOOP-->だけ解説してみます。
 制御タグの解説の前に、HTML::Templateモジュールを使う準備と、出力の方法を解説します。
 まず、モジュールを使うときにはお決まりのuseディレクティブを使います。

use HTML::Template;

 そしてHTML::Templateのインスタンスを作ります。

$tmpl = HTML::Template->new(filename => 'tmpl.html');

 newメソッドの詳しい使い方はPODを参照して下さい。一般的にはテンプレートファイルを読み込むでしょうから、 filename => ファイル名 として読み込むテンプレートを指定して下さい。
 これで準備が出来ました。後はparamメソッド経由で色々設定した後出力と言う流れでしょう。
 出力にはoutputメソッドを使います。outputメソッドは文字列を返すので、print関数なんかで受け取ってお好きな所に出力します。

# 標準出力への出力
print $tmpl->output();
# ファイルへの出力
open(FILESTREAM, ">hoge.html");
print FILESTREAM $tmpl->output();
close(FILESTREAM);

 次に制御タグの意味とスクリプト側での使用方法です。
 <!--TMPL_VAR NAME="hoge"-->は、この場所に文字列を挿入します。
 Perlスクリプト側では、HTML::Templateモジュールのインスタンスにparamメソッドを通してNAMEで指定した名前に対して文字列を設定します。

use strict;
use HTML::Template;
my $tmpl = new HTML::Template(filename => 'tmpl.html);
$tmpl->param(hoge => 'hogepiyofuga');

 <!--TMPL_LOOP NAME="piyo"-->はテンプレートにループ構造を与えます。<!--TMPL_LOOP NAME="piyo"-->と<!--/TMPL_LOOP-->で括られた範囲内にある物を反復表示する事になります。範囲内に<!--TMPL_VAR-->が無いと空ループになり何も挿入しないことになるようです。
 スクリプト側は<!--TMPL_VAR-->に比べると複雑になります。paramメソッド経由で設定した名前にオブジェクトを与える事自体は<!--TMPL_VAR-->と変わりませんが、<!--TMPL_LOOP-->に相当する名前に与えるオブジェクトは、<!--TMPL_LOOP-->内に置いた<!--TMPL_VAR-->に対応したハッシュへの参照の配列への参照になります。ややこしいですね。

# <!--TMPL_LOOP NAME="piyo"--><!--TMPL_VAR NAME="hoge"--><!--/
TMPL_LOOP--> に対するparamメソッドの例
use strict;
use HTML::Template;
my $tmpl = new HTML::Template(filename => 'tmpl.html);
my @tmpl_loop;
push(@tmpl_loop, { hoge => 'hoge' });
push(@tmpl_loop, { hoge => 'piyo' });
push(@tmpl_loop, { hoge => 'fuga' });
push(@tmpl_loop, { hoge => 'foo' });
push(@tmpl_loop, { hoge => 'bar' });
push(@tmpl_loop, { hoge => 'baz' });
$tmpl->param(piyo => \@tmpl_loop);

 多重にループした場合とてもややこしくなるので気を付けましょう。多重ループの可能性が高そうなtableタグ関連にはHTML::Tableというモジュールもあるのでそちらを使っても良いかも知れません。
 以上ざっと説明しましたが、CGIを作ったりしてる方、この機にHTML::Templateを使ってみては如何でしょうか?

また余計なことを……orz

Filed in Perl, prog

 何度か書いてるHTMLジェネレータなんですが。
 Wiki化だけでは留まらずクラス化までされてしまいました。
 コンストラクタかセッターを介して必要な情報を設定するか、情報を取得する為の関数をアタッチしてゲッターを呼び、print関数に出力メソッドの返り値を与えるとHTMLが吐き出される仕組みです。
 何でこんな事をするかというとUIとロジックを分離したかったからなんですね。所謂API化です。
 おかげさまで情報を入力する為のドライバつかラッパがコマンドラインでの対話とソーステキストを喰わせる形で実現されました。さらにCGIとPerl/TkなGUIも予定されてます。どうせ自分で使うのはソーステキスト版だけなのにね。
 ついでとばかりにソーステキストからの生成用にリストファイルを喰わすと自動的に全部トランスレートしてくれるトランスレータドライバとか作ってみたりもしてみたり。さらにリストファイルじゃなくてディレクトリ名喰わせるとサブディレクトリまで含めてソースファイルを探し出してトランスレートしてくれる機能も予定。
 なんだか楽しくて手が止まりません(´∀`)
 つかもう良いからさっさと移転作業しろよ……orz

switch文がほすぃ (perl)

Filed in Perl, prog

 今までのエントリでも書いた様に只今Perlでもにょもにょしてるわけですが。
 なんかね、if-elsif-elseブロック書いてると欲しくなるんですよswitch文。
 そこで擬似的に実現する方法を考えてみますた。
  1.ブロックを利用する方法
my $var = 検査される値;
switch:{
  $var =~ /条件文字列/ && do{
    処理;
    last switch;
  }
}
 2.配列やハッシュを利用する方法
$var = 検査される値;
@switch_a = {
  &{ 処理; },
};
&{$switch_a[$var]};
%switch_h = (
  key => &{ 処理; },
);
&{$switch_h{$var}};
 ハッシュを使った方法なんかは割と多用しとります。
 例えばCGIなんかでモード毎の処理に飛ばすときなんかは以下の様にやります。
%command_do = (
  RSS => \&do_RSS,
  write => \&do_write,
);
&{$command_do{$mode}};
sub do_RSS{
  (snip)
}
sub do_write{
  (snip)
}
 これ割と重宝します。YukiWikiなんかでも使われてます。
 興味有る方お試しあれ。


Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
Oenology Post Formats
Click to view/hide

Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
Posts Calendar
Click to view/hide
2017年11月
« 12月    
 1234
567891011
12131415161718
19202122232425
2627282930  

Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
アーカイブ
Click to view/hide

Warning: sprintf() [function.sprintf]: Too few arguments in /home/users/2/lolipop.jp-dp07042166/web/wordpress/wp-includes/widgets.php on line 1042
最近の投稿
Click to view/hide