トップページ⇒php
1001コメント371KB

Perlコーディング初心者質問スレ Part 43

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2005/08/12(金) 01:26:47ID:mHnZWvqz
Perlのコーディングで困ってる人のスレです。

【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。

1: 自分はこういう事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。

最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。

過去ログやお勧めサイトは >>2-10
0314nobodyさん2005/09/05(月) 01:21:54ID:???
sub TrafficPlus {
  my $plus = shift;  # 増加量
  my $Trafic_min_limit = 202400;
  my $Trafic_Timeout = 60;
  my $now = time;  # 現在時刻

  my %traffic;  # 転送量

  # ファイルから転送量情報を読み込む。
  open(IN, 'traffic.dat');
  my %in = split(/,/, <IN>);
  close(IN);
  for ( keys %in ) {  # $Trafic_Timeout秒以前の情報を捨てる
    $traffic{$_} = $in{$_} if ( $_ > $now - $Trafic_Timeout );
  }
  $traffic{$now} += $plus;

  my $sum;  # 指定時間内の転送量合計
  for ( keys %traffic ) {
    $sum += $traffic{$_};
  }

  # 転送量情報を保存。
  open(OUT, '> traffic.dat');
  print OUT join(',', %traffic);
  close(OUT);

  if ( $Trafic_min_limit > $sum ) {
    TrafficError();
  }
}
0315nobodyさん2005/09/05(月) 06:55:48ID:???
perl 5.8 でPPMを使ってGDをインストールしようとしたのですが出来ませんでした
GDインストール解説サイトに5.8はまだPPMが使えないのでActivePerlは5.6をインストールするように書いてありました
その解説は2004年9月に書かれたものですが
現在も5.8ではPPMは使えないのでしょうか
0316nobodyさん2005/09/05(月) 08:41:06ID:???
GD 2.25ならあるみたい。ppmで
rep add theoryx5 http://theoryx5.uwinnipeg.ca/cgi-bin/ppmserver?urn:/PPMServer58
としてから
search GD
で見つかると思う
0317nobodyさん2005/09/05(月) 10:34:21ID:???
>>315
有難う御座います
いまから試してみます
03183042005/09/05(月) 11:26:42ID:???
転送量の件できたっぽいので一応報告しときます。↓の奴で今のところ正常に動いてます。ありがとうございました。
sub TrafficPlus{
$plus = $_[0];
#現在の転送量保存
 my $Traffic_now = 'traffic.now.hidden';
#全体の転送量保存
 my $Traffic_total = 'traffic.total.hidden';
#現在の転送量を保存したときの時間
 my $Traffic_time= 'traffic.time.hidden';
#現在の時間
 my $nowTime=time;
&filelock('tr.lock');
 #現在の転送量取得
  $ntraffic = `cat $Traffic_now`;
 #保存したときの時間を取得
  $straffic = `cat $Traffic_time`;
 #現在の時間と保存したときの時間差取得
  $ptime = $nowTime - $straffic;
 #指定時間を超えていた場合リセット
  if($ptime > $Traffic_Timeout){$ntraffic = 0;$straffic = $noTime;}
 #現在の転送量に新たな転送量を加える
  $ntraffic += $plus;
  $straffic += $plus;
 #現在の転送量をファイルに記録する
  `echo '$ntraffic' > $Traffic_now`;
  `echo '$straffic' > $Traffic_total`;
  `echo '$nowTime' > $Traffic_time`;
&fileunlock('tr.lock');
if($ntraffic > $Traffic_min_limit){&TrafficError;}
return ($Traffic_now,$Traffic_total);
}
0319nobodyさん2005/09/05(月) 11:34:24ID:???
あーチョッと2行書き忘れていたので行数の関係上注釈無しで入れときます。

sub TrafficPlus{
$plus = $_[0];
  $Traffic_min_limit = 500000;
  $Traffic_Timeout = 60;
  my $Traffic_now  = 'traffic.now.hidden';
  my $Traffic_total  = 'traffic.total.hidden';
  my $Traffic_time  = 'traffic.time.hidden';
  my $nowTime=time;
&filelock('tr.lock');
    $ntraffic   = `cat $Traffic_now`;
    $straffic   = `cat $Traffic_time`;
    $ptime    = $nowTime - $straffic;
    if($ptime > $Traffic_Timeout){
        $ntraffic = 0;
        $straffic = $noTime;
    }
    $ntraffic += $plus;
    $straffic += $plus;
    `echo '$ntraffic' > $Traffic_now`;
    `echo '$straffic' > $Traffic_total`;
    `echo '$nowTime' > $Traffic_time`;
&fileunlock('tr.lock');
    if($ntraffic > $Traffic_min_limit){&TrafficError;}
return ($Traffic_now,$Traffic_total);
}
0320nobodyさん2005/09/07(水) 13:59:48ID:oYntvDxu
NFSとかサーバ設定関係は一切いじらず、2サーバのファイルを
同時に書き込むような仕組みでなにかよい方法はございます
でしょうか。
この2サーバはロードバランサーで動作しております。

現在は各サーバに受け側CGIを設置(ファイル書き込みCGI)。
それぞれのサーバにアクセスがあった場合、SOCKET通信で
もう一方のサーバのCGIを叩く仕組みでファイルの同期を取って
いるのですが、アクセスが集中したりすると
「Resource temporarily unavailable」とエラーが出たりしてしまい、
多少怒られております。

何かよい案があればご教示いただけますでしょうか。
宜しくお願いいたします。
0321nobodyさん2005/09/07(水) 20:41:36ID:3mQbsuSc
シロートな質問ですいませんが、どなたか教えて下さい。

<A href=http://a.jp/abc.cgi?menu=1>;メール</A>
というリンクでabc.cgiへ移るとき、メニュー番号をmenu=1で渡すと同時に
<INPUT TYPE=\"hidden\" NAME=\"id\" VALUE=$wk_id >でIDとパスワード
も渡すことはできないでしょうか?そもそもhiddenはフォームのボタン等
がクリックされた場合のみで、リンクの場合には渡せないのでしょうか?
リンクでID、パスワードを渡すとアドレスに表示されるので、できれば
hidden等が良いのですが。

よろしくお願い致します。
0322nobodyさん2005/09/07(水) 20:50:01ID:???
Perl関係ねーぞ

<A>のリンクでhrefにアドレスを設定するのではなく、
onClickでJavascriptのfunctionよんで、そこでsubmitさせる
0323nobodyさん2005/09/07(水) 20:50:14ID:???
>>320
CGIを動かしてる鯖以外に、ファイルサーバを導入する。しかないような…。

しかも、Resource temporarily unavailableのメッセージはhttpdが出してるやつでしょ?
単なるアクセス制限だからCGIのコーディングと関係ない。
0324nobodyさん2005/09/07(水) 20:53:03ID:???
>>321
JavaScript を使えばできますよ。

<a href="http://hoge/abc.cgi?menu=1" onclick=〜>
# onclick で呼ばれる関数で post メソッドで submit (CGI呼び出し)。

それか素直に、button にしておくか。この場合でも、
<form method=POST action="./abc.cgi?menu=1">
としておくと、URLには menu=1 が現れる。

上記いずれの場合でも、CGI側で menu と id の値を両方取得可。

# JavaScript と HTML の細部の記憶は曖昧なのでスペルミス等あれば悪しからず。
0325nobodyさん2005/09/07(水) 23:53:10ID:???
>>323
ご返答有難うございます。

アクセス制限ですか。
とくに認証等はかけてないのですが、接続数制限という意味でしょうか。
0326nobodyさん2005/09/07(水) 23:59:39ID:???
>>325
他で管理している鯖ですか?

認証は関係ありません。
制限自体は、その鯖の設定によりけりです。
単位時間あたりの接続数、ヒット数、転送量、など
いろいろな情報を元に制限をかけることが可能です。

制限がヒット数になっていて、そのページに画像が多い場合、
すべてヒットとカウントされて制限に引っかかることもあります。
0327nobodyさん2005/09/08(木) 00:24:20ID:???
>>320
あれ?ちょっと変じゃないですか??

ロードバランサ入れてるんですよね。
一方のCGIが叩かれた時に、もう一方のCGI叩いたらダメでしょ。
負荷分散してる意味が無いような…。
0328nobodyさん2005/09/08(木) 01:46:08ID:???
>>326
CGI側ではどうすることもできないんですね。
サーバの設定を見直してもらいます。

>>327
一部だけファイルを同期する必要があるので、この手法を
とりました。
0329nobodyさん2005/09/08(木) 03:24:01ID:vnFPn7Ff
%test = (
2 => '2です',
6 => '6です',
'Y' => '12です'
);

このようなハッシュを

foreach my $key (sort { $a <=> $b || $a cmp $b } keys %test) {
print "$key\n";
}

こう並べ替えますと、なぜか

Y
2
6

になってしまいます。

2
6
Y

にしたいのですが、
ご教示いただけますと幸いです。
0330nobodyさん2005/09/08(木) 04:23:02ID:???
>>329
Yは数値じゃないから$a <=> $bの時点で0と見なされてる。
0331nobodyさん2005/09/08(木) 04:24:19ID:???
そのハッシュキーだけなら
sort { $a cmp $b }
でいいんじゃね?
0332nobodyさん2005/09/08(木) 04:27:51ID:???
むしろデフォルトのsort keys %testでいいっしょ。
03333292005/09/08(木) 11:27:17ID:???
皆様、ご返答有難うございます。

実はこの部分、サブルーチン化していて使いまわして
いるので何かよい方法はないかと思っていたのですが、
$a <=> $b の数値比較のあとに $a cmp $bが評価されて
いないのではなく、$a <=> $bの時点でYが0になっていたの
ですね。

このルーチンは多くのところで使われておりますが、$a cmp $b
に統一するよう検討してみたいと思います。

本当に有難うございました。
0334nobodyさん2005/09/08(木) 13:51:44ID:+KUBGHaQ
会員登録のシステムを製作中です。
ログをどうするか悩んでいます。
プレインテキストで数千件の登録を管理するのは可能でしょうか。
また不可能だとすればどういう方法があるでしょうか。
是非ご教示願います。
0335nobodyさん2005/09/08(木) 15:06:45ID:???
>>334
コーディングと関係の無い話だと思います。
0336nobodyさん2005/09/08(木) 15:35:52ID:???
>>334
数千程度なら平気じゃないかな。
しかし信頼性は低いので、SQL使うのが速いし安全かと。
0337nobodyさん2005/09/08(木) 19:09:08ID:vnFPn7Ff
負荷について教えていただきたく思っているのですが、

sub send_socket{
 use Socket;
 my ($host, $filename, $data) = @_;
 my $path = "$filename?$data";
 my $return_value;
 my $port = getservbyname('http','tcp');
 my $iaddr = inet_aton("$host") or return 0;
 my $sock_addr = pack_sockaddr_in(80,$iaddr);
 socket(SOCKET,PF_INET,SOCK_STREAM,0) or return 0;
 connect(SOCKET,$sock_addr) or return 0;
 select(SOCKET);
 $| = 1;
 select(STDOUT);
 print SOCKET "GET /$path HTTP/1.0\r\n\r\n";
 while(<SOCKET>) {m/^\r\n$/ and last;}
 while(<SOCKET>) {$return_value .= $_;}
 close SOCKET;
 return $return_value;
}

これで内容を取得するのと

sub send_socket{
 my @wget_status = `/usr/bin/wget -q -O - "http://$host/$path"`;
 foreach (@wget_status){ $return_value .= $_; }
 return $return_value;
}

これで取得するのとでは同等という考えではございませんでしょうか。
ご教示いただけますと幸いです。
0338nobodyさん2005/09/08(木) 19:32:32ID:???
>>337
単に負荷と言われても、どこに注目するかによって違うので、一概には比べられない。

上のは、スクリプトの部分が多い。
下のは、プロセスをforkしてる。
0339nobodyさん2005/09/08(木) 20:26:41ID:???
>>338
100アクセス/secくらいのキャンペーンサイトで後者を使用
するのですが、非常に不安で胃がいかれそうです。。
何かアドバイス等ございましたら何でもよいのでいただけ
ますと幸いです。
0340nobodyさん2005/09/08(木) 21:12:24ID:???
>>339
コケそうな感じですね…。
どうしても後者なら、キャンペーン中だけでも
鯖で起動できるプロセス数を引き上げておかないと…。
0341nobodyさん2005/09/08(木) 21:29:41ID:???
>>340
前者だったらいけそうなのでしょうか。
まだ半日くらい猶予があるので、違いがあるのであれば
前者を検討してみたいと思います。
アドバイスいただけますと幸いです。
0342nobodyさん2005/09/08(木) 21:51:45ID:???
教えて君ですみません。

偉い人に聞いてみたところ、「uname -nで分かるノード名を使って通信して、
2台のサーバのファイルの同期を取れ」といわれたのですが、一体Perlで
どのようにしてこのような通信ができるのかが全く思い浮かびません。

これ以上何も教えてくれそうもないので調べてみたのですが、これといった
答えも見つからず呆然としております。

2台は同ネットワーク上にあるものです。

ご教示いただけますと非常に助かります。
0343nobodyさん2005/09/09(金) 00:20:57ID:???
@AA10 = ( 0, 1, 2, 3, 4 );
$BB = 10;
$CC= '$AA' . "$BB" . "[0]";

$CC を表示させると $AA10[0] となってしまいます。
どうしたら $BB などの文字を変えずに「0」と表示できるのでしょうか?

よろしくお願い致します。
0344nobodyさん2005/09/09(金) 00:23:35ID:???
>>343
print eval($CC);
03453432005/09/09(金) 00:56:01ID:???
>>344
無事表示されました。
本当にありがとうございました。
0346nobodyさん2005/09/09(金) 01:35:56ID:DzBAr2be
半角スペースを全て&nbsp;に置換したいのですが、
タグ内部まで変換されてしまって困っています。

 <font size="7"> ほげほげ </font>

$text =~ s/ /&nbsp;/g;をすると

 <font&nbsp;size="7">&nbsp;ほげほげ&nbsp;</font>
    ~~~~~~~
になってしまいます。
タグ内部を除いた部分だけを置換するにはどうしたらいいでしょうか?
0347nobodyさん2005/09/09(金) 01:41:53ID:???
スレ違いです。

正規表現道場@2ch Part4
http://pc8.2ch.net/test/read.cgi/php/1105930285/
03483292005/09/09(金) 04:28:01ID:???
sortのことで質問させていただいたものです。

たしかに
%test = (
2 => '2です',
6 => '6です',
'Y' => '12です'
);
は
foreach my $key (sort {$a cmp $b} keys %test) {
print "$key\n";
}
で

2
6
Y

こうなりましたが、たとえばキーに10や100といった数字が入っていると、
一番上にきてしまいます。

数字順>英数字という優先順位で並び替えるにはどうしたらよいのでしょうか。
0349nobodyさん2005/09/09(金) 06:19:11ID:???
sub sortfunc {
if ($a =~ /[^0-9]/ && $b =~ /[^0-9]/) {
$a cmp $b;
} elsif ($a !~ /[^0-9]/ && $b !~ /[^0-9]/) {
$a <=> $b;
} elsif ($a =~ /[^0-9]/ && $b !~ /[^0-9]/) {
1;
} elsif ($a !~ /[^0-9]/ && $b =~ /[^0-9]/) {
-1;
}
}
foreach my $key (sort sortfunc %test) {
print "$key\n";
}
まあもっといい方法あるかな?
03503492005/09/09(金) 06:28:21ID:???
%test→keys %testで
0351nobodyさん2005/09/09(金) 06:44:26ID:???
>>348
print map { "$_\n" } sort {
  $a !~ /^\d+$/ <=> $b !~ /\d+$/ ||
  $a <=> $b ||
  $a cmp $b
} keys %test;
0352nobodyさん2005/09/09(金) 08:09:10ID:???
さらに混ぜっ返しつつ warnings clean に。

print map "$_\n",
  sort {
    return $b =~ /^\d+$/ ? $a <=> $b : -1 if $a =~ /^\d+$/;
    return $b !~ /^\d+$/ ? $a cmp $b : 1;
  } keys %test;

>>348 のケースだと四行目は単に $a cmp $b; でもヨシだけれど、1 と -1 を交換すると逆のニーズにも対応できるという噂。
0353nobodyさん2005/09/09(金) 11:49:05ID:???
>>341
半日っていうともう猶予は過ぎてるかも知れないけど、>>338は
Perl始めたばかりのド素人のようだから無視するように。

mod_perlを使っていないのなら下の案はwgetを子プロセスとして起動する分、
サーバー負荷は無条件に高い。
単純計算で1アクセスにつき無条件にperlとwgetで計2プロセスが起動される
ことになる。wgetの中で上のコードと同じようなことをやっているのだから、
上の案のほうが負荷は半分になると考えていいだろう。

しかしそんなにアクセス数が見込まれるサイトがHTTP経由でデータ取得を行う
なんていうアホな設計になっているところが信じられん。
03543482005/09/09(金) 11:50:39ID:???
皆様、私にはレベルが高すぎです。
本当に有難うございます。

とりあえず一旦

foreach my $key (sort k::sort_rule keys %$refs) {
print $key;
}

sub sort_rule{
return $b =~ /^\d+$/ ? $a <=> $b : -1 if $a =~ /^\d+$/;
return $b !~ /^\d+$/ ? $a cmp $b : 1;
}

こんな感じで後で試してみようかと思います。
結果は追ってご連絡いたします。
0355nobodyさん2005/09/09(金) 12:06:18ID:???
>>353
有難うございます。
あれから実はソケット通信をやってみたのですが、エラーが出てしまったんです。

Object not found!
The requested URL was not found on this server.

If you entered the URL manually please check your
spelling and try again.

If you think this is a server error, please contact
the <a href="mailto:webmaster@localhost">webmaster</a>.

Error 404

localhost.localdomain

それで偉い人に聞いてみたら、「uname -nで分かるノード名を使って通信して、
2台のサーバのファイルの同期を取れ」とか言われたのですが、これがさっぱり
わからず、もうどうにでもなれといった感じでオープンが近づいております。。

ノードを名取った後どのような処理をすればよいのか、もしもご存知のようでしたら
ご教示いただきたく思っております。
0356nobodyさん2005/09/09(金) 15:06:48ID:???
>>355
なんか予想の斜め上をいく展開だな。

とりあえずその偉い人に
同一セグメントのサーバ同士のファイルの同期をとるのが目的なら
いっそのことNFSかsambaかWebDAVでディレクトリを共有したらどうですか?
と進言してみたら?

リアルタイム性を要求されないのならrsyncとかも使える。
0357nobodyさん2005/09/09(金) 17:24:02ID:???
>>352
>>351だが、351のコードで warnings 出るっけ?
それとも他のコードのことかな。
0358nobodyさん2005/09/09(金) 17:56:17ID:???
>>357
数じゃない文字列を <=> で比較すると use warnings 下では

Argument 〜 isn't numeric in numeric comparison (<=>) at 〜

が出ることをいってるんじゃないだろうか。

0359nobodyさん2005/09/09(金) 18:18:45ID:???
>>356
NFS等の導入は一番初めに提案させていただきましたが、
上から許可がおりないとか何とかであっさり却下されました。。

もうどうしたらよいのやら。。
0360nobodyさん2005/09/09(金) 19:22:09ID:???
>>358
なるほど。サンクス。勉強になりました。
たしかに暗黙の型変換を利用してるなぁ。
0361nobodyさん2005/09/09(金) 20:40:27ID:???
>>359
プロジェクト全体が腐ってるっぽいな。
404になる件はノード名を/etc/hostsに登録すれば
なんとかなるだろうが…

0362nobodyさん2005/09/10(土) 10:54:03ID:???
>>359
ヘッポコ上司に連座させられたくなかったら、
ちゃんとしたプロマネつれてこないとポシャルと、
上司を飛び越してその上の上司に進言しなさい。

>>361
> 404になる件はノード名を/etc/hostsに登録すれば
> なんとかなるだろうが…
ならない。
0363nobodyさん2005/09/10(土) 11:15:29ID:???
$count=0;
open(LOG,"$logfile");
$count += tr/\n// while(read LOG, $_, 1024);
close(LOG);

どうしてこれで$logfileの長さをカウントできるのか教えてください。
3行目のtr/\n// while(read LOG, $_, 1024);がよく分かりません。
0364nobodyさん2005/09/10(土) 11:15:52ID:???
404というエラーが正常に返ってきているのだから、接続はできているのだ。
0365nobodyさん2005/09/10(土) 11:19:09ID:???
>>363
ファイルのサイズではなく、行数をカウントしてるのでは。

ちなみに
open(LOG, $logfile);
の方が良いと思います。余計な変数展開がなくなります。
03663632005/09/10(土) 11:22:57ID:???
>>365
行数でした。
C言語しか知らないもので、while(条件){実行する内容}
という形式は理解できるのですが、perlではwhile文はどのように展開されるのでしょうか?
0367nobodyさん2005/09/10(土) 11:34:44ID:???
>>366
while を後置しているだけです。スクリプティング言語では多く見られます。

以下と同じ意味です。
while (read(LOG, $_, 1024)) {
$count+= tr/\n//; # trは置換に成功した数を返す。
}
0368nobodyさん2005/09/10(土) 11:34:57ID:???
>>366
perlのシンタックスの勉強なら本を買え。
0369nobodyさん2005/09/10(土) 11:47:10ID:???
>>367
>スクリプティング言語では多く見られます。
これ本当なの
Perl独自の変態仕様じゃないの
0370nobodyさん2005/09/10(土) 11:49:30ID:???
>>369
Perlから広まっていった…と記憶してる
0371nobodyさん2005/09/10(土) 15:15:07ID:???
trをやめてchompで。
0372名無しさん@そうだ選挙に行こう2005/09/11(日) 16:20:19ID:yhvSpEP/
モジュールを使わずにSHA-1ハッシュ関数を生成しようと思い以下のサブルーチンを拾ってきて以下の2つのサーバーでprint &SHA("a");を試したんですがサーバー1の方で正しいハッシュ関数が生成されてないみたいです。
サーバー1: Fedora Core release 3, Kernel 2.6.9-1.667, Perl version 5.8.5
サーバー2: FreeBSD 5.4-STABLE, Perl v5.8.2
どうすればよろしいでしょうか?
sub SHA {
### &SHA("squeamish ossifrage\n");
### Should return 82055066 4cf29679 2b38d164 7a4d8c0e 1966af57
  local ($temp, $m, @A, @K, $x, $n);
  local ($b, $c, $d, $e, $S, $r, @W, $t, $v);
  my ($msg, $p, $l) = @_; #$p=0; $l=0
  my $inputp=$_[0];
  local $_;
  $temp = 'D9T4C`>_-JXF8NMS^$#)4=L/2X?!:@GF9;MGKH8\;O-S*8L\'6';
  $m = 4294967296;
###$m=1+~0;
  @A=unpack"N*",unpack "u",$temp;
  @K=splice@A,5,4;
sub M{($x=pop)-($m)*int$x/$m};
sub L{$n=pop;($x=pop)<<$n|2**$n-1&$x>>32-$n}
@F=(sub{$b&($c^$d)^$d},$S=sub{$b^$c^$d},sub{($b|$c)&$d|$b&$c},$S);
do{
  $msg=~s/.{0,64}//s;$_=$&;
  $l+=$r=length;
  $r++,$_.="\x80"if$r<64&&!$p++;@W=unpack N16,$_."\0"x7;$W[15]=$l*8
if$r<57; for(16..79){push@W,L$W[$_
-3]^$W[$_-8]^$W[$_-14]^$W[$_-16],1}($a,$b,$c,$d,$e)=@A;
  for(0..79){$t=M&{$F[$_/ 20]}+$e+$W[$_]+$K[$_/20]+L$a,5; $e=$d; $d=$c;
   $c=L$b,30; $b=$a; $a=$t}$v='a'; @A=map{ M$_+${$v++}}@A
}while$r>56;
return sprintf'%8x'x4 . '%8x',@A;
}
03733482005/09/11(日) 16:54:25ID:???
遅ればせながら、ご報告させていただきます。

foreach my $key (sort k::sort_rule keys %$refs) {
 print $key;
}

sub sort_rule{
 return $b =~ /^\d+$/ ? $a <=> $b : -1 if $a =~ /^\d+$/;
 return $b !~ /^\d+$/ ? $a cmp $b : 1;
}

これでいきました!本当に有難うございました!
まだまだ技術レベルが低いので意味がわかってないのですが、
これから勉強してこの構文を十分理解できるようになりたいと
思います。

ご教示、誠に有難うございました。
0374名無しさん@そうだ選挙に行こう2005/09/11(日) 23:02:31ID:moSzhZBr
$_が分かりません。
説明を読むと、デフォルトの変数として、省略されている場合も
自動的に代入や出力されている特殊変数とあるのですが、たとえば
if ($_[0] eq 'bye') {
いきなりこんなのが出てきた場合、一体何をしてるんでしょうか。
自動的に配列を作って、0に何かが代入されている?

うかがうのに妥当なスレがないようだったので、こちらで尋ねました
よろしくお願いします。
0375名無しさん@そうだ選挙に行こう2005/09/11(日) 23:05:32ID:???
スクリプトの第一パラメータとか
サブルーチンの第一引数とか
0376名無しさん@そうだ選挙に行こう2005/09/11(日) 23:07:43ID:???
> スクリプトの第一パラメータとか
0377名無しさん@そうだ選挙に行こう2005/09/11(日) 23:12:45ID:???
>>374

@hoge = (1 ,2, 3);
↓
$hoge[0] == 1

@_ = (1 ,2, 3);
↓
$_[0] == 1

ok?
03783742005/09/11(日) 23:22:07ID:???
>375,>376,>377
レスありがとうございます。
>377の例、わかりやすかったです
特に個別に名前はつけてないけどこーゆー配列(変数)だよ、っていう事なんでしょうか。

もしかしてすごくアホな事聞いてるかもしれないんですが、さっきの
if ($_[0] eq 'bye')
コレ、いきなり出てきたんです。>377で言う@_ = (1 ,2, 3); みたいなのがなくて。
@_ = (1 ,2, 3); がないのに、一体何と比較してるんだろう???となってしまったんですが…
0379名無しさん@そうだ選挙に行こう2005/09/11(日) 23:29:33ID:???
>>378
サブルーチンの引数は、勝手に @_ に入ります。
というか、基本なんだからマニュアルか、本を読もうよ…。
03803742005/09/11(日) 23:37:29ID:???
>379
すみません。実は本読んでもよくわかりませんでした。
もうちょいスクリプトいじってみて、悩んでみます…
0381名無しさん@そうだ選挙に行こう2005/09/11(日) 23:41:56ID:???
>>380
その本、巻末に索引付いてませんか?
そこで、$_ と @_ を探しましょう。
0382nobodyさん2005/09/12(月) 17:57:25ID:???
たとえば、
-----
$classname = 'bar'
return "foo::".$classname->new();
-----
みたいに、変数に入ってる値でクラスを呼び出すことはできないのでしょうか?
(この例だと、foo::barを呼び出したいです)
foo::??の??の部分を変数にして動的に変えたいですが、何かやり方はありますか?
0383nobodyさん2005/09/12(月) 18:25:32ID:???
eval
0384nobodyさん2005/09/12(月) 20:53:06ID:???
>>382
use strict; を使ってるなら

no strict 'refs';

使ってないなら

$a = 'aaa';
&{$a."::new"}();
0385nobodyさん2005/09/12(月) 20:54:01ID:???
あら、上手くかけてなかった。

use strict; を使ってるなら

no strict 'refs';
$a = 'aaa';
&{$a."::new"}();

使ってないなら

$a = 'aaa';
&{$a."::new"}();
0386nobodyさん2005/09/12(月) 20:56:53ID:???
strict使ってないなら
$obj = "foo::$classname"->new();
もできるんじゃないかな。
0387nobodyさん2005/09/12(月) 21:23:44ID:???
>>386
おお、ほんとだ。
strict 使ってても、no strict 'refs' でOKみたい。
0388nobodyさん2005/09/12(月) 22:46:32ID:Giee4nr4
CGI.pmでのテーブルタグの出力ってどうやればいいんですか?

print table(TR,(td("")));

この書き方だとエラーになるようなんですが
0389nobodyさん2005/09/13(火) 10:56:07ID:???
>>387
no strictで制限を緩めるときはブロックに閉じ込めて必要最小限の
範囲だけにした方がいいよ。
0390nobodyさん2005/09/13(火) 11:31:37ID:???
質問です。
ファイルを開いて処理する時に

open (FILE,"<$list");
while(<FILE>){
chomp;
my (undef,$addr,$svr,$uer,$pass) = split(/<>/,$_);
&get($addr,$svr,$usr,$pass);
}
close FILE;

と、

open (FILE,"<$list");
my @getlist = <FILE>;
close FILE;
foreach my $usrdata(@getlist){
chomp($usrdata);
my (undef,$addr,$svr,$uer,$pass) = split(/<>/,$usrdata);
&get($addr,$svr,$usr,$pass);
}

ってどちらが速いいですか?
会社の人は「whileよりforeachのほうが速い」って言うのですが、
何回ベンチ取ってもwhileのほうが1割近く速くなるんです。
私のベンチの取り方が問題?

読み込むファイルの大きさは1kb程度のものです。
0391nobodyさん2005/09/13(火) 12:15:30ID:???
>>390
その例ならwhileの方が普通は早そうでベンチとも一致する。

my @getlist = <FILE>;

でファイル全体を一行ずつにばらした配列を作るのが余計な
手間になるからね。

ただ一般的には往々にして直観はあてにならないのできちんと
ベンチをとって評価するのが正道。
0392nobodyさん2005/09/13(火) 12:28:09ID:???
なにこの初心者
0393nobodyさん2005/09/13(火) 14:15:39ID:???
ファイルが巨大だったらメモリも食うし一括読み込みはあかん
03943822005/09/13(火) 14:15:41ID:???
384さん
386さん
うまくいきました。ありがとうございました。
0395nobodyさん2005/09/13(火) 14:32:09ID:???
>>389
サンキュ。そこまで書いたほうが親切だったね。
0396nobodyさん2005/09/13(火) 20:13:08ID:???
便乗して質問させてください。
掲示板CGIなどで、特定の投稿を編集をするとき、一括読み込みをしないでデータを書き換える方法はありますか?
0397nobodyさん2005/09/13(火) 21:19:34ID:???
書き換え前後のサイズ(文字数)とかが同じなら可能。
0398nobodyさん2005/09/13(火) 23:40:10ID:???
>>392
お前にもそういう時期があったろう
03993902005/09/14(水) 00:52:53ID:???
>>391
>>393
ありがとうございます。

会社の人が言うように、whileよりforeachのほうが速いケースってあるんだろうか・・・
と思う今日この頃。
0400nobodyさん2005/09/14(水) 01:35:33ID:???
>>399
ファイルから逐一読み出す処理よりも、
変数から処理するほうが速いって意味だったとか。
0401nobodyさん2005/09/14(水) 23:20:56ID:???
標準入力された画像データをPerlMagickで直接加工したいのですが・・・
use CGI;
use Image::Magick;
$cgi = new CGI;
$fh = $cgi->param('picFile');

$i = new Image::Magick;
$i->Read($fh); #これができない

print "Content-type: image/jpeg¥n¥n";
$i->Write('jpeg:-'); #何も出力されない

フォームで選択されたファイルをどうにかしてファイルハンドルとして
PerlMagickに読み込ませたいのですが、うまく行きません。

現在は標準入力のデータを一旦ファイルに書き出し、
それを読み込んで加工する方法を取っておりますが、明らかに非効率だと思うのです。
いい方法はございませんでしょうか。
0402nobodyさん2005/09/14(水) 23:24:25ID:???
$fh = $cgi->param('picFile');
04034012005/09/14(水) 23:57:54ID:???
>$fh = $cgi->param('picFile');
$fhはファイルハンドルじゃないってことですか?
でも
read($fh, $buf, 1024);
という風にできるから・・・
0404nobodyさん2005/09/15(木) 01:10:00ID:???
>>403
PerlMagickと組み合わせて使ったことはないのでよくわからんが、
ファイルハンドルがほしいのなら

$fh = $cgi->upload('picFile');

を使う方がいいんじゃないかと。(ただしCGIモジュール2.47以降)

詳しくはCGIモジュールのPODの「CREATING A FILE UPLOAD FIELD」を
をよく読むといいだろう。
0405nobodyさん2005/09/15(木) 13:41:48ID:3HNHstci
ローマ字を平仮名になおしたいんですが
s/ba/ば/g;
s/bi/び/g;・・・・みたいに何十行もえんえん続けるようなのでなく、
もっと効率的に動いて効率的に書けるような方法ありますか?
0406nobodyさん2005/09/15(木) 14:12:50ID:???
>>405
そおんなもんとっくに誰かが作ってるだろうと思い検索したらあったよ
ttp://pitecan.com/OpenPOBox/romakana/
04074012005/09/15(木) 15:53:13ID:???
>>404
uploadとは盲点でした。が、状況は変わらず・・・。
ファイルハンドルを渡す時は
$i->Read(¥*fh);
とするとリファレンスあったので、これも試してみました。

PerlMagickにこだわるあまりCGIの方が疎かになっているようなので、
色々可能性を模索したいと思います。
0408nobodyさん2005/09/15(木) 16:33:46ID:???
>>407
ファイルハンドルのときは

$i->Read(file => $fh);

だと思うが。
04094012005/09/15(木) 17:18:27ID:???
>>408
あ、ほんとだ。リファレンスにも書いてあるし、何故見落としてたんだろう・・・orz
おかげさまでうまく行きました。ありがとうございました。
0410nobodyさん2005/09/16(金) 08:23:19ID:0dogEF/n
すみませんすみません。
本当に申し訳ないです

知らない方がいらっしゃるのであれば申し訳ないのですがネットゲーム「罪と罰」のようなCGIを利用し、
複数のプレーヤーの様々な数値(ステータスなど)を参加者全体で共有するどういった内容で行なわれているのでしょうか?


ついでにもう一つの質問を。スレ違いな感はありますがどうか答えてやってください。
PerlとPHPが多くのCGIで利用されているようですが二種類の言語が存在するということは各々に得手不得手があるということですよね?
その得手不得手及び私が制作しようとしているCGIゲームではどちらが向いているのか、初心者ではどちらが学びやすいか教えてもらえるとかなり光栄です。
よろしくお願いします。

自分の質問…あまりにも馬鹿なのか基本的すぎるのか検索にすらHitしないんです…orz
0411nobodyさん2005/09/16(金) 08:31:10ID:???
>>410
もう少しちゃんと調べような。
http://www24.big.or.jp/~obo/game/ore_/gild/
これはPerlで書かれてる模様。

2つ目の質問はスレ違いだが、これ以上他のスレに誤爆されても困るので答えておく。
まずCGIと言う形では向いていない。
罪と罰もそうだけど、このタイプの設置を禁止している鯖も多い。
そしてCGIにはRubyやPython、JAVAもあればCもある。
要約するとこうだ、半年ROMってろ。
0412nobodyさん2005/09/16(金) 08:32:08ID:???
直リンスマソ。
半日ROMってくる
0413nobodyさん2005/09/16(金) 09:32:49ID:???
>>412さん
う〜ん…
自分は船乗りなので海の上でできる趣味が無いかな?と思ったんですけどねぇ…。
本で勉強してからまた書き込みます。まずは罪と罰と同じPerlから購入してみようと思います。
オススメの書籍があるならばお教えください。
レス無くとも言われたとおりROMっているので気を悪くしないでください。
■ このスレッドは過去ログ倉庫に格納されています