Perlコーディング初心者質問スレ Part 57
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2008/02/25(月) 19:25:51ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。
お勧めサイトは >2 以降
前スレ http://pc11.2ch.net/test/read.cgi/php/1189939783/
過去ログ倉庫 ttp://user.ftth100.com/mirrorhenkan/perl/
0577nobodyさん
2008/05/27(火) 20:56:48ID:???「perl スコープ 変数」でググっみ。
0578nobodyさん
2008/05/27(火) 21:53:15ID:???0579nobodyさん
2008/05/27(火) 22:34:53ID:???sub func {
my $temp = $_[0];
return defined( $_[1] ) ? $_[1] : $temp;
}
ex :
$foo = func( $foo, 10 ); # $foo = 10
$foo = func( $foo ); $foo = 1
0580nobodyさん
2008/05/28(水) 00:31:36ID:???0581nobodyさん
2008/05/28(水) 01:24:48ID:???0582576
2008/05/28(水) 01:29:54ID:???$global_bar = $bar = 2;
@_ = (3,4); #@_に値あり
{
my $foo;
my $bar;
$foo = $_[0];
$bar = $_[1];
$foo = $global_foo unless defined $foo;
$bar = $global_bar unless defined $bar;
print "point 1: foo=$foo bar=$bar\n";
}
print "point 2: foo=$foo bar=$bar\n";
出力結果
point 1: foo=3 bar=4
point 2: foo=1 bar=2
0583576
2008/05/28(水) 01:32:06ID:???$global_bar = $bar = 2;
@_ = (3,4); #@_に値あり
{
my $foo;
my $bar;
$foo = $_[0];
$bar = $_[1];
$foo = $global_foo unless defined $foo;
$bar = $global_bar unless defined $bar;
print "point 1: foo=$foo bar=$bar\n";
}
print "point 2: foo=$foo bar=$bar\n";
出力結果
point 1: foo=1 bar=2
point 2: foo=1 bar=2
━━━━━━━━━━━━━━━━━━━━━━━
うん、欲しかった動作そのままだけど。
>>577-578が理解できず悩み中
0584nobodyさん
2008/05/28(水) 01:34:02ID:???【誤】@_ = (3,4); #@_に値あり
【正】@_ = (); #@_に値無し
orz 120秒規制が若干きつい…
0585nobodyさん
2008/05/28(水) 01:35:51ID:???0586nobodyさん
2008/05/28(水) 01:46:51ID:???目的が分からん。そもそも何がしたいの?
説明する気あるのか?
my $foo = 1;
my $bar = 2;
print $foo = func( $foo );
print $bar = func( $bar );
print $foo = func( $foo, 3 );
print $bar = func( $bar, 4 );
exit;
sub func {
return defined( $_[1] ) ? $_[1] : $_[0];
}
0588576
2008/05/28(水) 01:58:37ID:???サブルーチン冒頭にて、引数リスト > デフォルト値(グローバル変数の値とか)
の優先順でmy変数値を設定したいことはよくあるから、
perlなら… perlならきっとすごくスマートに書く方法があるに違いない…
という夢を見たけど、幻だったみたいですね…
変数ひとつずつシコシコとunless definedを当てることにします。
0589nobodyさん
2008/05/28(水) 02:00:25ID:???お前の望むようなことは確実にできると思うんだけど、
なにぶん言いたいことがよく分からんw
0590nobodyさん
2008/05/28(水) 02:16:48ID:???my $global_bar = my $bar = 2;
# @_ =( );
@_ =( 3, 4 );
{
my $foo = defined( $_[0] ) ? $_[0] : $global_foo;
my $bar = defined( $_[1] ) ? $_[1] : $global_bar;
print "point 1: foo=$foo bar=$bar\n";
}
print "point 2: foo=$foo bar=$bar\n";
結局、最初に提案されてる回答をアレンジすれば、
>>582-584をシンプルかつ可読性も保ったまま実現できるんだが。
これじゃいかんの?
0591nobodyさん
2008/05/28(水) 02:25:18ID:???そのへんが限界みたいですね…ありがとうございます。
私の欲求そのものが十分特殊だったのかな…
いま考えてる最善の形はサブルーチンを使うことです。
サブルーチンコールは負担かかりそうだからやりたくないんだけど…
sub merge_argument_and_default{
my ($argument, @default) = @_;
my @value;
while(1){
my ($a, $v) = (shift @$argument, shift @default);
my $c = ((defined $a) ? $a : $v);
last unless defined $c;
push @value, $c;
}
return @value;
}
sub foo{
my(@bar) = &merge_argument_and_default(\@_, @default_bar);
}
みなさんありがとうございました。
0592nobodyさん
2008/05/28(水) 02:30:59ID:???0593nobodyさん
2008/05/28(水) 06:17:52ID:???もう実装されてるよ?
http://search.cpan.org/dist/perl/pod/perl5100delta.pod#Defined-or_operator
0594nobodyさん
2008/05/28(水) 06:40:31ID:???当初の目的をすり替えて、自分は違うもの作ってました的な発言するやつは質問にくるなよ。
当初は「>>569をコンパクトにしたい」って言ってただけなのに、
どんな解が提示されても、
どんどん違う方向に勝手に転換して善意のレスすら流し読み。
こういう奴は、治らないから本当に放置すべきだと思うよ。
0595nobodyさん
2008/05/28(水) 07:18:42ID:???それは違うんだけど、あなたへの説得は無理かな。
ひどく機嫌を損ねてしまったのは悪いと思ってるが。
いただいたありがたいアドバイスから、例えば今回は、
「サブルーチン化でもしなければ相当コンパクトに収めるのは難しいらしい」
「そのサブルーチンはこういう形で書くのがよいのだろうか」
などと、自分の知識や興味対象は移り変わっていくことが多いです。
ただ、このスレッドにはしばらく書き込みを自粛します。さよなら。
0596nobodyさん
2008/05/28(水) 10:11:34ID:???0597590
2008/05/28(水) 10:39:10ID:???目的も明確にせず、そのへんが限界てw
そもそも次の疑問に移ったなら、その過程を説明するのが回答者への最低限の礼儀だろ。
社会出て苦労するよ。
ちなみに>>591は、俺ならこう書く。
sub merge_argument_and_default {
my ($argument, @default) = @_;
my %count;
$count{$_} = $default[$_] for( 0..$#default );
$count{$_} = ${ $argument }[$_] for( 0..$#{ $argument } );
return map { $count{$_} } sort keys %count;
}
0598nobodyさん
2008/05/28(水) 11:40:59ID:???言葉遣いが丁寧なだけで、いっぱしの大人だと思ってる人。
0599nobodyさん
2008/05/28(水) 12:04:01ID:???>>598
ガキなの見え見えなんだよねw
ttp://www2.atpages.jp/mirror/2ch/perl/prog/read.php/1157874614/
の595を思い出した。
0601nobodyさん
2008/05/28(水) 15:44:58ID:???5.8より昔のリリースだとしか思えない。
0602nobodyさん
2008/05/28(水) 15:51:58ID:???Ver 5.010000
こう書けばよいのか?
0603nobodyさん
2008/05/28(水) 16:09:29ID:???知らなかったorz
0604nobodyさん
2008/05/28(水) 16:21:25ID:???苦肉の策なんだろうな……。
0605nobodyさん
2008/05/28(水) 17:55:49ID:???0607nobodyさん
2008/05/28(水) 20:28:19ID:???この$ipが存在するか、あるテキストファイル(ip.txt)を読んで
チェックしています。以下は例です。
$ipは"192.168.0.1"
ip.txtに192.168.0.1が記述してあります。
この場合マッチするようプログラムしてあります。
ip.txtに
192.168.0.0/24
または
192.168.0.0/255.255.255.0
と記述してあるものと
マッチさせたいのですが、
そういうサブルーチンは
ありますでしょうか?
簡単にいうと、あるIPアドレスが
サブネットマスクで指定してある
10進表記またはサイダー表記に
マッチするか判定したいのです。
ip.txtは10進表記でもサイダー表記の
どっちでも構いません。
0608nobodyさん
2008/05/28(水) 20:34:04ID:???の543-544及び「IP pack unpack perl」でググれ。
0610597
2008/05/28(水) 21:17:34ID:???終わった話題なんだけど、ちょっと気になった。
めんどくさかったら、スルーして。
提示してくれてるルーチンだと、
引数1 @array1 = ();
引数2 @array2 = ( 1,2 );
のとき、返り値が空になっちゃうよね。
配列1(引数1) > 配列2(引数2) という優先順位で、
配列3(返り値)を混ぜ合わせるというのが目的の処理だと思うんだけど、
配列1と配列2で要素数の大きい配列を、要素数だけループさせる処理にする場合、
キレイにまとめる方法ってないかなぁ?
if( ( $#array1 <=> $#array2 ) == -1 ) {
EXPR for( 0..$#array2 );
} else {
EXPR for( 0..$#array1 );
}
みたいな、冗長な方法しか俺には思い浮かばなかった。
だから、「配列の重複値をハッシュを利用してマージ」の応用みたいなことを>>597でやってみたわけだ。
なんか美しい方法あればいいんだけどなぁ。
0612597
2008/05/28(水) 21:26:18ID:???こんな前処理してから、>>599のmap対象配列に、( 0..\$temp ) って感じかなぁ?
エレガントさには欠けるけど、これが可読性保つギリギリかな?
0613597
2008/05/28(水) 21:28:46ID:???0615599
2008/05/28(水) 22:23:24ID:???ああ、
@array1 = ( undef, undef ) ;
は考えてたけども、それは想定してなかったw
>>612の解で良いんじゃね? 助長を厭わないならば、
map{ 略 } 0 .. $#{$_[0]} , 0 .. $#_ - 1 ;
っつー荒技もw
自分のスクリプトじゃ絶対やんないけどね。
0617nobodyさん
2008/05/29(木) 03:05:45ID:???覚えると便利そうだけど。
0618nobodyさん
2008/05/29(木) 03:45:40ID:???違うっていえば、{}の中を、引数リストのそれぞれの要素で実行した結果をリストとして返すってとこか。
かなり便利な局面もある。覚えとくべきだとは思う。
@res = map{ $_ + 10 } (1,2,3,4,5) ;
print join("\n",@res);
---結果---
11
12
13
14
15
$_->[0] += 1900;
$_->[1]++;
@$_;
}[(localtime)[5,4,3,2,1]];
2008/05/28 07:02
って出るかと思う。
0620nobodyさん
2008/05/29(木) 08:23:18ID:???シュワルツ変換という定番sort手法には必須だよ。
ぐぐって、foreach 文で書いてみたらありがたみが分ると思う。
>>619
お前さんの例は頻繁にとんでもなく斜め上を行くなあw
なんで一要素しかないと分りきってる無名配列を作って map の例にする?
do ならいざしらず
perl -le 'my $Now_Date = sprintf qq|%04d/%02d/%02d %02d:%02d|, do{
@_ = (localtime )[5,4,3,2,1] ;
$_[0] += 1900 ;
$_[1] ++ ;
@_ } ;
print $Now_Date ;'
それ以前に普通は↑こんな面倒な事しないだろ?
perl -MPOSIX=strftime -le '$str =strftime "%Y/%m/%d %H:%M", localtime; print $str, "\n"; '
0621607
2008/05/29(木) 17:51:57ID:???IPアドレスのチェックを行いたいと思ってます。
ググると、以下の様な正規表現がありますが、
\d(バックスペース)の意味が分かりません。
どういう意味なんでしょうか?
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}
0622nobodyさん
2008/05/29(木) 17:53:57ID:???0623607
2008/05/29(木) 17:54:42ID:???\dは数字でした。
申し訳ない
0624607
2008/05/29(木) 18:10:05ID:???正規表現で/をマッチさせたいのですが、
以下であってますでしょうか?
$hoge =~ /\//
0625607
2008/05/29(木) 18:11:58ID:???\/で、いけるみたいです。
お騒がせしました。
0626nobodyさん
2008/05/29(木) 18:15:31ID:???すこしは綺麗?
0627nobodyさん
2008/05/29(木) 18:19:11ID:???シュワルツ変換とかまだいまいち理解できないけど良さそうだね。
sortは結構使うから思い処理の部分で使うのはいいかも。
でも問題は後で読み直して何してるか理解できなくなりそうな所だな。
つっこみおおきに♪
mapを覚えちゃってからどんどん斜め上に逝っちゃいました。
ひとまず車輪の再発明は大好き♪
0629nobodyさん
2008/05/30(金) 02:09:30ID:???0630nobodyさん
2008/05/30(金) 08:17:40ID:???0631nobodyさん
2008/05/30(金) 10:14:07ID:???0632nobodyさん
2008/05/30(金) 10:19:32ID:???0633nobodyさん
2008/05/30(金) 11:57:18ID:???を書くとローカルで文字化けしてしまいます。これをコメントアウトすると
XREA.COMのサーバ上でScript Errorが発生してしまいます(しかもエラーログが見られない)。
ローカルでもXREA.COM上でも動くようにしたいのですがどうすればいいでしょうか。
コードはこんな感じです。
#!/usr/bin/perl
use strict;
use XML::DOM;
use encoding "utf8";
my $xhtml_file = $ENV{'PATH_TRANSLATED'};
my $parser = new XML::DOM::Parser;
my $doc;
eval { $doc = $parser->parsefile($xhtml_file) };
if($@) {
print "Content-Type: text/plain;charset=utf-8\n\n";
print "parsing error occured: $@";
exit;
}
# 広告挿入処理
print "Content-type: application/xhtml+xml;charset=utf-8\n\n";
print $doc->toString;
$doc->dispose;
ローカルの環境はUbuntu 8.04 + Perl 5.8.8 + Apache 2.2.8、
XREA.COMはよくわかりません。
0635nobodyさん
2008/05/30(金) 12:23:13ID:???utf8::is_utf8($doc->toString) ? print encode('utf-8', $doc->toString) : print $doc->toString;
とすればいいみたいです。utf8フラグというのが関係しているみたいなので、
調べてみます。おさわがせしました。
0637nobodyさん
2008/05/30(金) 12:50:11ID:???0638nobodyさん
2008/06/01(日) 07:19:24ID:???0639nobodyさん
2008/06/02(月) 12:34:35ID:???Last-Modified↑これをtimeの値に変換する方法を教えてください。
3600秒以内とかの判定に使いたいので。
0642nobodyさん
2008/06/02(月) 13:51:21ID:???$mon = 1 if $mon eq 'Jan';とか。
スマートな例があったら参考の為に見せてください。
sub last_modified {
my $time = shift;
my($day, $mon, $year, $hour, $min, $sec);
if ($time =~ /\w+, (\d+) (\w+) (\d+) (\d+):(\d+):(\d+) GMT/) {
($day, $mon, $year, $hour, $min, $sec) = ($1, $2, $3, $4, $5, $6);
$mon = 1 if $mon eq 'Jan';
$mon = 2 if $mon eq 'Feb';
$mon = 3 if $mon eq 'Mar';
$mon = 4 if $mon eq 'Apr';
$mon = 5 if $mon eq 'May';
$mon = 6 if $mon eq 'Jun';
$mon = 7 if $mon eq 'Jul';
$mon = 8 if $mon eq 'Aug';
$mon = 9 if $mon eq 'Sep';
$mon = 10 if $mon eq 'Oct';
$mon = 11 if $mon eq 'Nov';
$mon = 12 if $mon eq 'Dec';
} else {
die "Error: $time\n";
}
$time = timelocal($sec,$min,$hour,$day,$mon-1,$year);
return $time;
}
0643nobodyさん
2008/06/02(月) 14:47:28ID:???%mons = (
Jan => 1, Feb => 2, Mar => 3, Apr = 4, # ……以下省略
);
$mon = $mons{$mon};
とかどうよ?
0647nobodyさん
2008/06/02(月) 17:46:33ID:VCfcjQkNHTML::Template を使いたいのですが、
ローカルにインストールしている、
C:\Perl\cpan\build\HTML-Template-2.9\Template.pm
というファイルを、以下のcgiと同ディレクトリにコピーしました。
#!/usr/local/bin/perl
use strict;
use lib qw(.);
use HTML::Template;
print "Content-type:text/html\n\n", "test";
ですが、うまくいかないようです。
use lib qw(.); の部分を、
unshift @INC, '.';
などとしても不可能でした。
ググっても上記の方法ぐらいしか出てこないんですが、何がいけないか教えていただけますでしょうか。
Perl のバージョンは 5.00503 です。
0648nobodyさん
2008/06/02(月) 17:51:49ID:???0649nobodyさん
2008/06/02(月) 18:08:23ID:VCfcjQkNありがとうございます。
助言どおりHTML ディレクトリにTemplate.pmを入れて、エラーが出たので、
Digest::MD5がどうだとかエラーが出ました。
同じ要領で、Digest ディレクトリを作り、MD5.pmを入れると、
次はXSLoader.pmが必要らしく、それもcgiと同ディレクトリに入れました。
次はDynaLoader.pmがどうとかエラーが出たので、それも同じディレクトリに入れたのですが、
今度はエラーが消えませんでした。。
最終的にCGI::Carpがはいたエラーは以下です。
[Mon Jun 2 18:01:45 2008] Template.pm:
[Mon Jun 2 18:01:45 2008] Template.pm:
[Mon Jun 2 18:01:45 2008] MD5.pm:
[Mon Jun 2 18:01:45 2008] MD5.pm:
[Mon Jun 2 18:01:45 2008] DynaLoader.pm: Can't locate loadable object for module Digest::MD5 in @INC
(@INC contains: /usr/lib/perl5/5.00503/i386-linux /usr/lib/perl5/5.00503 /usr/lib/perl5/site_perl/5.005/i386-linux /usr/lib/perl5/site_perl/5.005 .) at HTML/Template.pm line 915
[Mon Jun 2 18:01:45 2008] Template.pm:
[Mon Jun 2 18:01:45 2008] Template.pm: BEGIN failed--compilation aborted at HTML/Template.pm line 915. BEGIN failed--compilation aborted at test.cgi line 6.
0650nobodyさん
2008/06/02(月) 18:17:18ID:???0651nobodyさん
2008/06/02(月) 18:18:22ID:???0652nobodyさん
2008/06/02(月) 18:25:00ID:VCfcjQkN↑必要としているモジュールは違うものの、
この人と同じ状況なのかな、と思うんですがどう思いますか?
同じ状況だとすると、不可能ですよね
FTPであげることしかできませんので。。。
0653nobodyさん
2008/06/02(月) 18:41:40ID:???Linuxでコンパイルし直さないとムリ。よってムリ。
0654nobodyさん
2008/06/02(月) 18:45:29ID:VCfcjQkN5.00503で使えるHTML::Templateの代わりのようなものがほしいんですが、
どこを探せばいいでしょうか。
何度も申し訳ありません。
0655nobodyさん
2008/06/02(月) 18:52:18ID:VCfcjQkN0656nobodyさん
2008/06/02(月) 18:56:19ID:???自前でテンプレート化した方が早い。
スキン対応と銘打ってる配布CGIのソース読んだ方が早い気がする。
0657nobodyさん
2008/06/02(月) 18:59:25ID:???0658nobodyさん
2008/06/02(月) 19:03:56ID:???ってか、>>649の内容を見るに、DynaLorderでわなくて、Digest::MD5(.so)が無いんでないの?(これも標準でない?)
まあなければ、Digest::MD5はXSモジュール含んでるから、
そのサーバー上でコンパイルし直さないと実行できないのは、>>653と同じ意見だけど。
0659nobodyさん
2008/06/02(月) 19:07:00ID:VCfcjQkNテンプレート使えないとなると、めんどくさくなるけど、まぁがんばります。
ありがとうございました。
0660nobodyさん
2008/06/02(月) 19:49:04ID:???HTMLと最も親和性のある言語として、Perl/CGIが一世風靡しただろ。
0663nobodyさん
2008/06/03(火) 00:57:17ID:etSjPPZKプログラムを作ったのですが
HTMLのformでenctypeをmultipart/form-dataにすると
送られてくるデータの形式が変わってしまって
うまくハッシュに確保することができなくなっちゃいました。
送られてきたデータが
multipart/form-dataなのか
application/x-www-form-urlencodedなのか
調べる方法ってありますか?
ついでに、multipart/form-dataで送られてきたデータの扱い方を
まとめてあるサイトとかありましたら教えてほしいです。
0664nobodyさん
2008/06/03(火) 01:01:53ID:???multipart/form-data の処理は CGI.pm 使ってね♪
0665nobodyさん
2008/06/03(火) 01:12:56ID:???CGI.pm ならどちらの形式でも意識せず受け取れる。
http://perldoc.jp/docs/modules/CGI.pm-2.89/CGI.pod
自前実装したいのなら
http://www.studyinghttp.net/cgi-bin/rfc.cgi?3875#Sec8.2
http://www.asahi-net.or.jp/~sd5a-ucd/rec-html401j/interact/forms.html#h-17.13.4.1
http://www.studyinghttp.net/cgi-bin/rfc.cgi?2388
0666nobodyさん
2008/06/03(火) 01:24:31ID:etSjPPZKありがとう!
0667nobodyさん
2008/06/03(火) 01:58:53ID:???テンプレートエンジン、自分で作るという手もある。
そんなに難しくないよ。
Compositeパターンでも使えば。
0668nobodyさん
2008/06/03(火) 09:41:38ID:???HTML をふつうに書く
HTML なかに <%BODY%> とか、挿入場所を示す識別子をいくつか用意して書き込む
プログラムからテンプレート HTML を読み込む
正規表現で置換
たったこれだけです。
0669nobodyさん
2008/06/03(火) 11:07:04ID:???HTML::Templateは単純な処理だしね
さくっと使いたい時には便利、無けりゃ無いでどうにでもなる
0670nobodyさん
2008/06/03(火) 12:56:41ID:K4KbdDUTそのCGIですべてを管理するような仕組みを作った場合
やっぱindex.cgiにアクセスが集中してよくなかったりするんですか?
0671nobodyさん
2008/06/03(火) 13:31:41ID:???自分は普通のエディタ (関数へのジャンプとか無くて色分けだけ) なので
まったく違う処理はファイル分けてる
0672nobodyさん
2008/06/03(火) 17:01:51ID:???それぞれ頭で同じ事やってるから、all.cgi(index.cgi?)に全て
まとめられないか?って事じゃないのかな?
my $cgi = CGI->new();
my $config = init();
if( $cgi->param('mode')eq'hoge1' ) {
require 'hoge1.pl';
hoge1::main($config);
} elsif( $cgi->param('mode')eq'hoge2' ) {
require 'hoge2.pl';
hoge2::main($config);
…って、感じで。漏れも昔、初心者だった時に同じ事を思った。
答えは、当然all.cgi(index.cgi?)の呼び出しのオーバーヘッドは
全CGIの呼び出し回数倍増えるよ。
そういう事じゃなくて??
0673nobodyさん
2008/06/03(火) 17:44:51ID:???俺それやってる
wikiみたいに書けるテキストファイルを自動で携帯/PCに最適化してValid XHTML出力する、みたいな。
0674nobodyさん
2008/06/03(火) 17:56:29ID:???0675nobodyさん
2008/06/03(火) 19:41:27ID:???企画倒れというより、制作者が途中で飽きて、ブームになっても、そのまま放置……みたいな。
かのCPANだって、一部のモジュール以外は、姥捨山みたいになってる。
古いモジュールに、パッチ送ってもメール不達とか多すぎるんだよ!
0676nobodyさん
2008/06/03(火) 20:52:43ID:???ここの 東京の xml から加工を行っています。
最終的には明日の天気を出力したいのですが、以下のコードを書いたところ
気温や降水確率が出力されなくて悩んでいます。
================================================
use XML::TreePP;
use strict;
my $tpp = XML::TreePP->new();
my $tree = $tpp->parsefile( '13.xml' );
print $tree->{weatherforecast}->{pref}->{area}->[1]->{info}->[1]->{weather} , "\n";
print $tree->{weatherforecast}->{pref}->{area}->[1]->{info}->[1]->{temperature}->{range}->[1];
================================================
{range}->[1] で %hash と言われてしまうのはどうしてでしょうか。
その後に [1]->{-centigrade} をするとこの場合は min が出てくるのは判っています。
■ このスレッドは過去ログ倉庫に格納されています