Perlコーディング初心者質問スレ Part 56
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
2007/09/16(日) 19:49:43ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。
お勧めサイトは >2 以降
前スレ ttp://pc11.2ch.net/test/read.cgi/php/1180492441/
過去ログ倉庫 ttp://user.ftth100.com/mirrorhenkan/perl/
0451nobodyさん
2007/10/29(月) 11:17:19ID:???指定した文字が何回続いたかを取得したいのですがどうしたらいいですか?
例)この場合指定した文字は1です。
$a = '1111222';
$b = '1111136';
$aは4
$bは5
よろしくお願いします。
0452nobodyさん
2007/10/29(月) 11:56:14ID:???全角はシラネ
0453nobodyさん
2007/10/29(月) 11:59:30ID:???$c= 1;
$n= length(($a=~/((?:\Q$c\E)+)/)[0])/length($c);
0454nobodyさん
2007/10/29(月) 12:31:05ID:???$a = '111111222';
$n = '1';
$count = length(($a =~ /($n+)/)[0]);
0455nobodyさん
2007/10/29(月) 13:04:18ID:???$test_str = '111234111111';
$char = '1';
こういう場合は後半気にせず、まず見つけた連続の 3 でいいの?それとも、より長い連続の 6?
「はい、6 が得られるようにしたいんです」だと上に回答を書いた皆さんが優しくキレるかも。
あと、例なんだろうけど $a や $b は地雷踏むことがあるから気をつけてね。
0456nobodyさん
2007/10/29(月) 13:25:31ID:???use warnings;
test('1111222' => 1 );
test('1111222' => 2 );
test('111122211' => 1 );
test('111122211' => 1 , 1);
test('1111136' => 1 );
sub test {printf "%s:%s:%s\n",$_[0],$_[1],_test(@_)}
sub _test {
local($a,$b);
(sort {$b<=>$a} map {length($_)} ($_[0] =~ m{($_[1]+)}g) )[ $_[2] ? -1 : 0 ];
}
0457nobodyさん
2007/10/29(月) 17:04:12ID:???print +( length ) . qq{\n} for split /[^$i]+/ ,$a ;
0458456
2007/10/29(月) 19:24:03ID:???sub _test { ( sort map length,$_[0] =~ /(${_[1]}{2,})/g )[$_[2] ? 0 : -1] }
0459nobodyさん
2007/10/30(火) 23:38:44ID:???例えば
$mode = $cgi->param('mode');
というデータを受け取って、処理の場合わけをする場合どういう書き方がエレガントなんでしょうか?
現状は
if ($mode eq 'post') { &post}
elsif ($mode eq 'edit') { &edit;}
elsif ($mode eq 'delete') { &delete}
else { &error}
こんな感じなのですが、それは初心者の書き方だって馬鹿にされました。
悔しいのでもっと効率的な方法があったら教えてください。
0460JAPU ◆lVJAPUTeX.
2007/10/30(火) 23:52:20ID:???エレガントかは分からないけど、分岐がある程度多い場合はこんな書き方だとすっきり書けるかと。
%actions = (post => \&post,
edit => \&edit,
delete => \&delete);
if(exists $actions{$mode}) {
$actions{$mode}->();
} else {
error();
}
数個程度なら if で分岐されちゃってもいいと思いますし、実際そうしています。
0461nobodyさん
2007/10/30(火) 23:58:03ID:???それでいいんじゃね?
各サブルーチンに戻り値があるなら「三項演算子」って手もあるし、
以下の様なやり方もあるけど、普通に書いてメンテ出来るものならば
バカにされても放置しとけば?
my %hash = (
post => sub { 1 } , # &post の内容を書く
edit => sub { 2 }, # &edit の内容
delete => sub { 3 }, # &delete の内容
) ;
print $hash{'edit'}->() || q{error} ; #q{error} には&error あたりを、、、
ソース全体を見たら綺麗な書き方があるかもしれんが、
それに関しては情報不足。
0462nobodyさん
2007/10/30(火) 23:59:04ID:???0463nobodyさん
2007/10/31(水) 00:10:35ID:???if文分岐も分かりやすいと思うが、へたに小細工するとますますへたっぴに見える。
0464nobodyさん
2007/10/31(水) 12:11:23ID:???使いたくない書き方No1かも。
0465nobodyさん
2007/10/31(水) 13:29:29ID:???: $expr3 ? $expr4
: $expr5 ? $expr6
: $expr7
;
書き方か頭が悪いんだろ
0466至急
2007/10/31(水) 15:17:23ID:???CGIに詳しく都内に来れる方であれば可能
一日日払い即金で払います。
詳細はメール下さい。
0467nobodyさん
2007/10/31(水) 15:47:41ID:???エレガントかしらないけどこんなパッケージ作ってる。
(不要箇所削ったのでそのまま動くか不明)
package Local::Base;
use strict;
use warnings;
our $DEBUG = 0;
sub class {ref$_[0]||$_[0]||__PACKAGE__}
sub new {(bless {} => class( shift() ))->init(@_)}
sub mode :method {shift->param('mode',@_)}
sub method_name :method {shift->{method_name}->{ shift() }}
sub default_method :method {die('不正なmodeを受け取りました')}
sub init :method {
my $self = shift;
my %param = @_;
$self->{method_name} = $param{method_name} || {};
return $self->run_method( $self->mode , @_ );
}
sub run_method :method {
my $self = shift;
my $method = $self->method_name( shift );
$method = 'default_method' unless $method && $self->can( $method );
return $self->$method(@_);
}
1;
0469nobodyさん
2007/10/31(水) 19:51:49ID:???使い方も書いたつもりだったんだけど書けてなかった。
#!/usr/bin/perl
use strict;
use warnings;
use base qw(Local::Base);
my $r = eval{
__PACKAGE__->new(
method_name => {
edit => 'edit',
post => 'post'
}
)
} || $@;
print CGI->header,$r,"\n" unless ref $r;
######################################################################
# editの動作を定義
sub edit :method {
my $self = shift;
print $self->header;
print "EDITモード";
return $self;
}
1;
0470nobodyさん
2007/10/31(水) 20:11:48ID:???この :method って何の意味だっけ
perlsub見ても載ってないや
変数にも付けれた気がしたが
0471nobodyさん
2007/10/31(水) 21:09:19ID:???perl attributes でググれば日本語のサイトも沢山出る。
変数に付けられるのは 5.8系
0472nobodyさん
2007/11/01(木) 01:06:18ID:???自分でゴチャゴチャ作るよりも。使ってる人いる?
0473nobodyさん
2007/11/01(木) 02:26:10ID:???0474nobodyさん
2007/11/01(木) 10:48:57ID:???CGI::Application もフレームワークじゃないの?
0475nobodyさん
2007/11/01(木) 17:27:41ID:???:methodは組み込みのattribute
Attribute::Handlers使うと自作のattributeも作れる。
…がいつ仕様が定まってなくて変更があるかもってどっかで読んだ気がする。
>>474
・自分しかいじらない
・少人数で知識の共有が容易
・マニュアルが整っている
のどれかなら自作のフレームワークの方が慣れてるだろうし開発効率いいんじゃないかな?
フレームワーク自体のメンテナンスが(出来る|しなきゃいけない)のはデメリットか?
既製のフレームワーク使うのは
・他の人と知識の共有しやすい
・ドキュメントがある/(第3者も使ってるので)ノウハウが検索しやすい
・フレームワーク自身のメンテナンスを(あまり)しなくていい
ってとこかな?
0477nobodyさん
2007/11/02(金) 11:22:36ID:???別名で保存するにはどうすればいいでしょうか
Perl 5.8.8なのでuse Encode;を利用する、読み取り専用で1行ずつ変換処理する
あたりまでは勉強しました。スマートな方法よろしく御教示おねがいします
0478nobodyさん
2007/11/02(金) 13:22:56ID:???データはutf-8のままのほうがよくないかな。
0481nobodyさん
2007/11/02(金) 16:43:20ID:???0482nobodyさん
2007/11/02(金) 17:17:33ID:???すげー!、シェルスクリプトですよね?
sshができない場合はこんな感じで利用すればいいのかな
system("nkf -s log.txt > log.sjis.txt");
1つ気になるのがjcode.plなど元の文字コードを指定するのがあると思うのですが、
&jcode::convert(\$_, 'sjis' ,'utf8');
nkfでは気にしなくても自動判別完璧なのでしょうか?
0483nobodyさん
2007/11/02(金) 17:34:58ID:???0484nobodyさん
2007/11/02(金) 17:51:47ID:???use Perl6::Slurp;
use Jcode;
$c = slurp "log.txt";
Jcode::convert(\$c, "sjis", "utf8");
open($fh, ">", "log.sjis.txt");
print $fh $c;
>>482
jcode, Jcode, nkfは、判別できる場合は判別してくれる。
0486nobodyさん
2007/11/05(月) 07:24:22ID:???コマンドプロンプトだとnslookup -> set type=***
UNIXならhost -t ***
でクエリタイプを設定できるんですけど、PERLの場合はどうやるのでしょうか。
0487nobodyさん
2007/11/05(月) 10:55:44ID:???http://search.cpan.org/~olaf/Net-DNS-0.61/lib/Net/DNS.pm#Find_the_nameservers_for_a_domain.
0488nobodyさん
2007/11/05(月) 11:20:15ID:6nXAnQ+nopen(FILE,">".$workFname) or die "Cannot Output File: ";
あらかじめファイルを持たせておいて、書き込み権限を与えておけば
成功しますが、新規にファイルを作成できません。
どうすればいいのでしょうか。
0489nobodyさん
2007/11/05(月) 12:21:09ID:???0491nobodyさん
2007/11/05(月) 13:19:35ID:???0492nobodyさん
2007/11/05(月) 13:22:45ID:???できれば相対パスのままで動くようにしたいです。どうすれば解決できるか分かる
方はおられませんか。まあ、あまり解決策が複雑なら、とりあえずあきらめてこの
ままにしておくつもりですが。
0493nobodyさん
2007/11/05(月) 14:36:06ID:???まず「何を」相対パスにしようとしているのかくらい書こうぜ。
あと「自分の環境」は書かなきゃ誰にも伝わらない。
0494nobodyさん
2007/11/07(水) 09:25:24ID:R3XG8Srf0496nobodyさん
2007/11/07(水) 11:46:06ID:R3XG8Srf#!perl/bin/perl
use strict;
sub kansu{
my $ref1 = shift;
my $value1;
foreach $value1($$ref1) {
print $value1 . "\n";
}
}
sub main{
my @databox1 = (13,1,6,3,9,8);
my $ref1 = \@databox1;
usort_kansu(@databox1);
}
main();
0497nobodyさん
2007/11/07(水) 11:47:42ID:???正: kansu(@databox1);
0498nobodyさん
2007/11/07(水) 12:36:16ID:???「言語的意味で」正しく挙動させるには
foreach $value1($ref1) {
(多分)あなたの望んだ挙動にするには
ソースの殆どに手を入れる必要がある。
∴ 本読んでからどうしても分らんかったら
質問し直せ
0499nobodyさん
2007/11/07(水) 14:24:36ID:???#!perl/bin/perl -w
use strict;
sub kansu {
my $ref1 = shift;
# my $value1;
foreach my $value1 (@$ref1) {
print $value1 . "\n";
}
}
sub main {
my @databox1 = (13,1,6,3,9,8);
my $ref1 = \@databox1;
kansu($ref1);
}
main();
0500nobodyさん
2007/11/07(水) 15:22:14ID:vLJSXT0R.qmailからperlスクリプトを呼び出しているのですが、その場合エラーログを取るにはどうしたらよいのでしょうか?
不正終了しているようなのですが、原因がつかめません。
0501nobodyさん
2007/11/07(水) 15:43:21ID:???if ($@) {
open(LOG, ">>/path/to/ログファイル名") or die;
print LOG "WARNING: $@";
close(LOG);
}
こういうスクリプトをqmailから呼び出せばどーよ
>499
forearch行を書き換える条件だからforearch my $value (@_){ って書いて欲しかったのかと・・
0502501
2007/11/07(水) 15:59:10ID:???こうか
0504nobodyさん
2007/11/07(水) 18:20:14ID:???ログが見えないならプログラムを置くべきではないと思う。
0506500
2007/11/07(水) 19:59:45ID:???qmailのログとはmaillogでしょうか?
スクリプトからは何もログを吐いていないんです。
sudoでapache権限で実行してるからログ吐かないのかな。
0507nobodyさん
2007/11/07(水) 20:05:11ID:???0510500
2007/11/07(水) 22:29:30ID:???いえ。
.qmail内でperlのみsudoしてapache権限で動かしてます。
qmailはvpopmail権限で動かしてますよ。
>>507さんでログ取れました。m(__)m
0511nobodyさん
2007/11/09(金) 15:33:58ID:???0514nobodyさん
2007/11/09(金) 17:49:37ID:???0515nobodyさん
2007/11/09(金) 18:08:33ID:???0516nobodyさん
2007/11/09(金) 18:57:53ID:???0518nobodyさん
2007/11/09(金) 19:09:09ID:8S2oyKnmuse dan;
で解決するよ。
0519nobodyさん
2007/11/09(金) 19:26:50ID:???0520nobodyさん
2007/11/09(金) 21:31:54ID:???0521nobodyさん
2007/11/09(金) 22:28:46ID:???0522nobodyさん
2007/11/09(金) 23:35:40ID:8S2oyKnm0523nobodyさん
2007/11/09(金) 23:39:07ID:???0524nobodyさん
2007/11/10(土) 10:49:28ID:Z9OcedPCさらにその圧縮ファイルを解凍するスクリプトを作りたいです。
例えば、LWP::Simpleを使った場合
my $dat = get('http://hoge.com/071110.lzh');
の後はどう処理していけばいいでしょうか?
0525nobodyさん
2007/11/10(土) 11:02:39ID:???lha 書庫を解凍する処理を行えばよい。
0526nobodyさん
2007/11/10(土) 11:03:28ID:???はい。
http://www.google.co.jp/search?q=lzh+%E8%A7%A3%E5%87%8D+perl&ie=utf-8&oe=utf-8
0527nobodyさん
2007/11/11(日) 02:16:45ID:???どうすればいいんでしょうか。
0529nobodyさん
2007/11/11(日) 14:32:10ID:4iiY3aOIurlからファイル名だけを取り出したいです。
例えば、$urlという変数に下の3つのurlがあった場合は
hoge1.html, hoge2.html, hoge3.htmlを取り出したいです。
http://localhost/hoge1/hoge1.html
http://localhost/hoge1/hoge11/hoge111/hoge2.html
http://localhost/hoge2/hoge21/hoge3.html
下のように自分でやってみたのですが、localhostの前の/から取得してしまいます。
if( $url =~ /\/(.*\.html)$/ ){
print $1 . "\n";
}
どうすればやりたい事ができますか?
教えてください、お願いします。
0530nobodyさん
2007/11/11(日) 14:35:11ID:???あ、とりあえず ?xxx=hoge とかの引数は考えなくていいよね?
0531529
2007/11/11(日) 14:47:19ID:???レス有難うございます。
>ワイルドカードにすべき部分は「全ての文字」じゃない、「/を除いた全ての文字」だ。
なるほど。でも頭では理解できてもそれをコーディングするとなると・・・
.*の部分を弄ればいいのかなぁ。
>あ、とりあえず ?xxx=hoge とかの引数は考えなくていいよね?
はい、このパターンは今回ありえないっす。
0532529
2007/11/11(日) 14:58:10ID:???if( $url =~ /\/([^\/]*\.lzh)$/ ){
正規表現すげー
>>530さんアドバイスありがとうございました。
0533nobodyさん
2007/11/12(月) 08:03:25ID:???0534nobodyさん
2007/11/12(月) 16:33:29ID:XNEEDQVz最初、linuxの fileコマンドを使用していたのですが誤認識がよくあり使えません。
バイナリなのかテキストなのかだけ分かればいいのですがperlでそれを行うにはどのようにしたら良いのでしょうか?
0535nobodyさん
2007/11/12(月) 16:42:39ID:???0536nobodyさん
2007/11/12(月) 18:17:28ID:XNEEDQVz有難う御座います。
試してみましたが、EUCだったり10文字程度のcp932などの場合に誤認識するようです。
0537nobodyさん
2007/11/12(月) 18:33:52ID:???それ以外だと各文字コードの仕様を調べて
全データがそれに矛盾してないか判断するしかないと思
0538nobodyさん
2007/11/12(月) 18:39:12ID:???0539nobody
2007/11/13(火) 03:52:36ID:fKqfq45H上のサイトのようなゲームをperlで作りたいと思っています。
htmlのみでも十分なゲームだとは思いますが、あえてCGIゲームとして作りたいです。
(学校の授業の自由課題であるので・・・)
一応以下のようにhtmlは作ってみました。
<html>
省略
<body>
<h1>オーケストラ楽器別診断</h1>
<p>次の質問にお答えください♪</p>
<form action="/nussknac/cgi-bin/kadai.cgi" method="post">
<dl><dt>お名前</dt>
<dd><input type="text" name="name" value=""></dd><br>
<dt>Q1. あなたはプライドが高いほうですか?</dt>
<dd><ul>
<li><input type="radio" name="answer1" value="Yes" checked>Yes</li>
<li><input type="radio" name="answer1" value="No">No</li>
</ul></dd></dl>
<p><input type="submit" name="send1" value="送信"><br></p>
</form></body></html>
0540nobody
2007/11/13(火) 03:57:04ID:fKqfq45HHTMLのフォームから情報をCGIに送り、最初の質問に対してYesならAの質問、NoならBの質問・・・というように
答えによって質問を分岐させるように作りたいです。
if文でひたすら分岐するというイメージはありますが、どうすれば、送信ボタンを押した時に次の質問ページにリンクさせる事ができるかが分かりません。
質問ページは一つ一つ作りたいです。
よろしくお願いします。
0541nobodyさん
2007/11/13(火) 04:18:50ID:???で、htmlはともかくどこまでperl書いたのよ。まさか1行も書かずに相談しにきてるわけじゃあるまい?
0542nobodyさん
2007/11/13(火) 06:54:14ID:???0543nobodyさん
2007/11/13(火) 08:58:39ID:???色々ロジックはあると思うけど、そこら辺はどうするのかな
0544nobodyさん
2007/11/13(火) 09:17:32ID:???提出日まで1〜2週間とかなら大丈夫じゃない?
その昔、C言語の授業があって、その授業終了直後に提出したら怒られたことがあったなあ(笑)
ごめん、確かに授業聞いてませんでした。
0545nobodyさん
2007/11/13(火) 09:19:51ID:???<li><input type="radio" name="answer" value="Aの質問のURL" checked>Yes</li>
<li><input type="radio" name="answer" value="Bの質問のURL">No</li>
ってして、
print "Location: answerの値\n\n";
でリダイレクトさせていけばいいだけでは?
0546nobodyさん
2007/11/13(火) 10:36:02ID:???0547nobodyさん
2007/11/13(火) 11:10:10ID:???元の文字コードがUTF-8のときは問題なく表示できるのですが、
文字コードの判別を含めてやる場合どうやったらいいのでしょうか?
Perlのバージョンは5ですが、プロバイダ(@nifty)のサーバーのため標準モジュールを使用できません。
いきなり変換が難しいならUTF-8か否かを判別できれば、
UTF-8の場合→直デコード
UTF-8でない場合→直デコード→jcode.plで変換
でいいのかもと考えているのですが、UTF-8か否かの判別法がわかりません。
よろしくお願いします。
0548nobodyさん
2007/11/13(火) 15:19:48ID:lcS1D/Cp一応perlでは以下のように作りました。
#!/usr/local/bin/perl
use CGI;
$query = new CGI;
$q1 = $query->param('answer1');
if ($q1 eq Yes) {
open(F, ">>q2.html");
} else {
open(F, ">>q3.html");
}
でもこれだとエラーが出てしまいます。
どのように直せばいいでしょうか。
リンクのさせ方など教えて下さい。
課題提出は12月までです。
違うスレには書いていないので私ではないです。
■ このスレッドは過去ログ倉庫に格納されています