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

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

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2011/09/09(金) 18:11:49.71ID:???
Perlのコーディングで困ってる人のスレです。

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

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

最低でも1と3が無いと誰も答えられないよ。
良い回答は良い質問から。一緒に勉強しましょう。

お勧めサイトは >>2 以降

前スレ http://hibari.2ch.net/test/read.cgi/php/1295170172/
0220nobodyさん2011/10/18(火) 22:33:11.15ID:???
DB使う。
0221nobodyさん2011/10/18(火) 22:58:12.17ID:???
>>219さんは$SIGを適切に設定してる感じですか?
0222nobodyさん2011/10/18(火) 23:25:30.92ID:???
$SIGなの? %SIGじゃないの?
0223nobodyさん2011/10/19(水) 00:20:24.38ID:???
$SIG{} って書いてから {} だけ消したので修正ミスです ^-^;
0224nobodyさん2011/10/19(水) 00:46:29.74ID:LOxxA4S5
GDで文字列を画像に変換するとき
widthを入力しないといけませんよね
全角文字だけなら計算できるのですが、半角英数カナなどが含まれるので余白が発生してしまいます。
あらかじめ文字列の長さをpixelで計算する方法はありませんか?
0225nobodyさん2011/10/19(水) 09:54:29.71ID:???
何も調べずに書くが
cp932に変換してバイト数を調べるのはどうか
0226nobodyさん2011/10/19(水) 10:42:15.21ID:???
>>224
@bounds = GD::Image->stringFT($fgcolor,$fontname,$ptsize,$angle,$x,$y,$string)
0227nobodyさん2011/10/19(水) 14:19:45.05ID:???
>>226
完璧です。ありがとうございました。
0228nobodyさん2011/10/21(金) 17:01:48.08ID:???
GD で機種依存文字を使えるようにするための方法はありますでしょうか
0229nobodyさん2011/10/22(土) 05:11:26.88ID:???
time_%2F_1319178123_%2F_name_%2F_%82r%82%81%81%99%82k%82%85%82%85_%2F_title_%2F_%82%BD%82%A2%82%C6%82%E9.txt

現在ファイルがopenできなくなると言う罠に陥りました。
windows7でこうゆうファイル名なんですが、コレ問題ありますか?
運用はunix系で考えているんでそっちでも問題あれば教えてください。
0230nobodyさん2011/10/22(土) 05:13:47.30ID:???
すみませんなんでもないですopenでしました。
0231nobodyさん2011/10/22(土) 09:48:47.25ID:???
>>230
「き」と「し」を打ち間違えるとは珍しい。
0232nobodyさん2011/10/22(土) 20:17:03.51ID:???
>>229をデコードしたヤシは挙手ノ
0233nobodyさん2011/10/22(土) 21:14:46.30ID:???
Sa☆Lee って何だ?
0234nobodyさん2011/10/22(土) 21:57:21.39ID:???
Sa☆Leeでぐぐったヤシは挙手ノ
0235nobodyさん2011/10/22(土) 22:19:39.38ID:???
なんかの罠かと思ってスルーしてた
0236nobodyさん2011/10/24(月) 13:03:32.39ID:???
ハッシュの中の配列に、値を追加したいときはどうすればできますか?

こうすると
push($h{$i}->[0], "aaa"));

このようなエラーになります。
Type of arg 1 to push must be array (not array element)
0237nobodyさん2011/10/24(月) 13:36:02.75ID:???
push @{$h{$i}}, "aaa";
0238nobodyさん2011/10/24(月) 13:50:46.81ID:???
>>237
上手くいきました。ありがとうございます。
こんな書き方理解できない。もうPerlやりたくない。
0239nobodyさん2011/10/24(月) 13:58:00.35ID:???
同じプログラムをRubyとPHPとPythonでは書き直せるんですけど、
Perlだけ作法が全然違うからわかわからないんですけど、どうすればいいですか?????????
0240nobodyさん2011/10/24(月) 15:33:37.66ID:???
Perl5.14でその配列が既に存在していれば、

use v5.14;
push $h{$i}, "aaa";

でいけるかな?
0241nobodyさん2011/10/24(月) 17:29:05.68ID:???
>>239
全然違うってほどのもんじゃないとは思うけど。
例えばどんなところが書き直せないの?
0242nobodyさん2011/10/24(月) 19:39:40.90ID:???
むしろその中だと、PHP←→Perlが一番簡単な気がするんだw
0243nobodyさん2011/10/24(月) 23:41:27.27ID:???
>>241
ハッシュとか配列とかの操作でカッコとか記号とかが覚えられない。
代入するときも表示するときもアクセスの仕方が違ったりして覚えられない。ダンプするのも一苦労。
クラスのnewのblessとか未だに何なのかわからない。祝福とは???
リファレンスとかスカラーとかレキシカルとか聞き慣れない用語ばかり出てくる。
スコープとかクロージャとかJavaScriptの悪夢がよみがえる。
とにかく記号ばっかりで暗号いじってるみたいな意味不明さが怖い。

$hoge; $hoge{0}; $hoge->{0}; @hoge; @hoge{0}; @hoge->{0}; %hoge; %hoge{0}; %hoge->{0};
${$hoge}; @{hoge}; @{$hoge}; {@{$hoge{0}}} @{$hoge->[0]}; %{$hoge->[0]}; %{$hoge->{0}}

どれだよ!!!!!!!!111111111
0244nobodyさん2011/10/24(月) 23:51:16.92ID:???
独特の表記とか用語に拒否反応ってのはわからんでもないけど、
スコープとかクロージャ駄目ってんじゃ他の言語もまともに使えてないだろ……
0245nobodyさん2011/10/24(月) 23:54:49.09ID:???
>>243
意味不明って、単にPerlを知らないだけでは。
慣れればおいしいよ。
0246nobodyさん2011/10/25(火) 00:14:38.50ID:???
$hoge; スカラ
$hoge{0}; ハッシュ
$hoge->{0}; ハッシュへのリファレンス
@hoge; 配列
@hoge{0}; エラー 配列へのアクセスは $hoge[0] でアクセス
@hoge->{0}; エラー 配列へのリファレンスは $hoge->[0] でアクセス
%hoge; 連想配列
%hoge{0}; 記述エラー 連想配列内の要素は $hoge{0} でアクセス
%hoge->{0}; 記述エラ 連想配列へのリファレンスは $hoge->{0} でアクセス

${$hoge}; スカラのデリファレンス
@{hoge}; エラー
@{$hoge}; 配列のデリファレンス
{@{$hoge{0}}} 連想配列内の配列をデリファレンス ($hoge{0} の中に配列が入っている) ただし外の {} は括る必要なし。 この場合 {} はブロックになる。
@{$hoge->[0]}; 配列へのリファレンスの中の配列
%{$hoge->[0]}; 配列へのリファレンスの中の連想配列
%{$hoge->{0}} 連想配列へのリファレンスの中の連想配列

こんな感じのも良く使うので覚えた方がいいかも。
$hoge = {
  'array' => [], 連想配列へのリファレンスの中に配列を作る
  'hash' => { 連想配列へのリファレンスの中に連想配列へのリファレンスを作る
    'key1' => 'val',
    'key2' => 'val',
  }
};
それぞれへのアクセスは
$hoge->{'array'}->[1];
$hoge->{'hash'}->{'key1'};
となる。
0247nobodyさん2011/10/25(火) 00:41:32.32ID:???
> @hoge{0}; エラー 配列へのアクセスは $hoge[0] でアクセス

エラーではない
が、スライスを理解して使っているわけではなく、たまたま動いているだけ、の初心者が多いと思う
02482472011/10/25(火) 00:42:17.13ID:???
{} と [] を見まちがえた。ごめん。
0249nobodyさん2011/10/25(火) 01:04:32.90ID:???
@hoge{0} なら %hoge に対するハッシュスライスでしょ
warnings 有効なら @hoge{0} は警告出るだろうが、
@hoge{0..2} とか、 my @keys = (0); @hoge{@keys} なら問題ないはず
0250nobodyさん2011/10/25(火) 01:31:51.65ID:???
指摘のある通り、%hoge; と宣言されてるなら @hoge{0} は動作する。

けどね。
質問者がくじけてる部分を考えたらスライスは考えないほうがいいのでは?
という意味からエラーっていうことにした。

まぁ、言葉が足りなかったってのもあるけど ^-^;
0251nobodyさん2011/10/25(火) 01:51:36.00ID:???
>>246
> @{hoge}; エラー
エラーではない。

全ての変数や関数へのアクセス方法で一番冗長な書き方は sigil { (何か) } ([添え字]|{キー})
の形で、何かが裸の語なら変数名、リファレンスならデリファレンス、
それ以外なら何かの値を名前としたシンボリックリファレンスと解釈される。
通常の変数へのアクセスは、裸の語をデリファレンスすると捉えてもいい。

${ foo } … 通常の変数。{} は*省略可能*。 ${foo} = "foo${foo}foo$foo"; # ok
${ "foo" } … シンボリックリファレンス
${ $foo } … スカラーリファレンス $foo をデリファレンス
${ 'f' . 'oo' } … 式の値を名前としたシンボリックリファレンス
${ \ foo('bar') } … foo('bar') の戻り値のリファレンスのデリファレンス

http://perldoc.jp/docs/perl/5.10.0/perldata.pod#Slices
> (引用注: 添え字/キーの) かっこの種類(大かっこか中かっこか)は、見ているものが配列か
> ハッシュかをつかさどっています。一方、配列やハッシュの先頭の記号 ('$' か '@') は、
> 返ってくるものが単一の値(スカラ)か、複数の値(リスト)かを示しています。

use warnings; my @{foo} = ('a'..'f'); my %{bar} = ('g'..'j');
print ${foo}[3]; # 'd' へのアクセスで "d" を表示
print @{foo}[3]; # 警告有り。('d') へのアクセスで "d" を表示
print @{foo}[3,4]; # ('d','e') へのアクセスで "de" を表示
print ${foo}[3,4]; # 警告有り。リストをスカラーとして評価すると最後の値が返されるので "e" を表示
print ${bar}{'g'}; # 'h' へのアクセスで "h" を表示
print @{bar}{'g'}; # 警告有り。('h') へのアクセスで "h" を表示
print @{bar}{'g','i'}; # ('h','j') へのアクセスで "hj" を表示
print ${bar}{'g','i'}; # キー "g$;i" へのアクセスになるので undef
0252nobodyさん2011/10/25(火) 03:20:14.95ID:???
> print ${bar}{'g','i'}; # キー "g$;i" へのアクセスになるので undef
これだけ知らなかったわ。awk 由来なのかな。
まあ積極的に使う意義は無さそうだし、
人のコードで見かけることもないから覚えなくてもいいよね。
0253nobodyさん2011/10/25(火) 22:21:51.58ID:???
>>243
> クラスのnewのblessとか未だに何なのかわからない。祝福とは???
blessは意味わからないよね。
あれ、祝福とか変な言葉で説明するからわからんのさw
オレ流に説明してあげよう。

まず、これを実行してみよう。Dumperは変数の中身を表示する関数だ。use Data::Dumperが必要。
my $a = {key=>1};
print Dumper($a)

以下のように表示される。(改行インデントは折りたたむ)
そう、ようするにただのハッシュだ。
$VAR1 = {'key' => 1};


次に次の命令を実行してみよう。
my $a = {key=>1};
bless($a, "CLASS");
print Dumper($a)

以下のように表示される。さっきのハッシュの周りにCLASSが追加されている。
VAR1 = bless(  {'key' => 1},  'CLASS' );

つまりだ、これはCLASSという名前のクラス名(モジュール名)付きのハッシュということだ。
このモジュール名付きのハッシュにたいして、以下のように->を使って呼び出しをすると、
$a->foo()

$aにはCLASSというモジュール名が結びついているため、CLASS::foo()を呼び出すんだなとPerl実行環境は理解できる。
その時CLASS::foo()の第一引数に$aを渡すことで、foo()の中で$aの値の操作することが可能にある。

これでCLASSクラスのfoo()メソッド呼び出しの仕組みと、$aをCLASSクラスのインスタンスに変換することができた。
0254nobodyさん2011/10/25(火) 22:33:18.24ID:???
もう一つ、$a->foo() という書き方。

$a に bless使ってCLASSと結びつけたハッシュが入っていれば、
CLASS::foo()が呼び出されるわけだが、

$aは文字列でもよい。つまり、
$a = 'CLASS';
$a->foo();
この方式でもCLASS::foo()が呼び出せる。
通常は、CLASSを$aに入れずにそのまま書いて、CLASS->foo() となる。

でこれが foo()じゃなくて new() だと、CLASS->new() となる。
呼び出されるのは、当然CLASS::foo(); そして foo() の第一引数にはCLASSという文字列が入っている。

これを利用してCLASS::newされた時に、CLASSに結びつけたハッシュ、
つまりCLASSのインスタンスを返すことで、Perlにおけるnewの仕組みとなる。

あと余談。殆どの場合ハッシュにCLASSを結びつけるのだが、
別にただの値にCLASSを結びつけるのも一応可能。
0255nobodyさん2011/10/25(火) 22:34:03.01ID:???
訂正
×呼び出されるのは、当然CLASS::foo(); そして foo() の第一引数にはCLASSという文字列が入っている。
○呼び出されるのは、当然CLASS::new(); そして new() の第一引数にはCLASSという文字列が入っている。
0256nobodyさん2011/10/25(火) 22:36:14.83ID:???
> あと余談。殆どの場合ハッシュにCLASSを結びつけるのだが、
> 別にただの値にCLASSを結びつけるのも一応可能。


ただの値にblessはできんか。
何かしらの値のリファレンスにblessできる。
0257nobodyさん2011/10/25(火) 23:11:45.61ID:???
system("wget $url");
を使ってファイルをダウンロードしたいのですがうまくいきません。
perl というかwget の使い方の問題なのかもしれませんが、
適切な書き方をご存知のかたがいらっしゃったらおしえていただけませんか?

ダウンロードしたいファイルは以下のURLです。
ttp://ncode.syosetu.com/txtdownload/dlstart/ncode/108715/?no=1&hankaku=0&code=utf-8&kaigyo=CRLF

エラーとしては、こう言われます。
index.html?no=2&hankaku=0&code=utf-8&kaigyo=CRLF: Invalid argument
Cannot write to `index.html?no=2&hankaku=0&code=utf-8&kaigyo=CRLF' (Invalid argument).
0258nobodyさん2011/10/25(火) 23:53:11.13ID:???
自分は、たまーにハッシュに名前が欲しくて bless する事もあるw

use LWP::Simple;
my $data = get('URL');

特に認証がなければ、これで取得できるかと。

自分は

use LWP::UserAgent;
use HTTP::Request::Common;
use utf8;
my $ua = LWP::UserAgent->new;
 〜agent とか timeout とか max_redirect とか cookie の設定〜
my $req = GET('URL');
my $res = $ua->request($req);
my $content = $res->code() eq '200' ? decode('utf-8', $res->content()) : '';

ってやってる。
手順が多いけど、自分の頭ではこの方が使いやすい。

$res->code() eq '200' の部分は $res->is_success とかで置き換えられるけど、回線がパンパンのときに失敗すると
is_success は 1 を返すので信用出来ない。
HTML の取得なら、$res->content() に </html> が含まれるかどうかで判断した方が良い。
つっても、殆どの場合は is_success や is_error は正しく動作する。
0259nobodyさん2011/10/26(水) 01:13:19.12ID:???
>>257
wget は特に指定がなければサーバのパスに対応するファイル名でローカルに保存しようとするから、
? はファイル名に使えねえよと言われてるのでは。Windows ないから試せないけど。

>>258
sub is_info ($) { $_[0] >= 100 && $_[0] < 200; }
sub is_success ($) { $_[0] >= 200 && $_[0] < 300; }
sub is_redirect ($) { $_[0] >= 300 && $_[0] < 400; }
sub is_error ($) { $_[0] >= 400 && $_[0] < 600; }
sub is_client_error ($) { $_[0] >= 400 && $_[0] < 500; }
sub is_server_error ($) { $_[0] >= 500 && $_[0] < 600; }
# HTTP::Status より。

失敗したにもかかわらず is_success が真を返すというなら、
まず疑うべきは LWP でなくサーバ側のレスポンスでは?
原因がクライアント/サーバ/回線/他のいずれにせよ、
負荷等が原因で200以外の2xxが返ってくる状況なんてちょっと想像つかんが。

decode('utf-8', $res->content()) はよっっっぽど古いバージョンの LWP じゃない限り
$res->decoded_content(charset => 'utf-8') のほうがよかろ。
0260nobodyさん2011/10/26(水) 01:38:17.35ID:???
>>259
失敗なのに is_success が成功を返すのは少々特殊な状況なのは分かってる。

自宅でサーバー動かしてて家のルータは BA8000Pro なんだけど、BitTorrent で Linux ISO を放流してる。
バージョンアップがくるとコネクションがすごい数やって来て、NAT のテーブルが溢れて (上限は 2600)
名前解決すら頻繁に失敗するほど不安定になる。

この状況下で LWP で GET とかすると is_success が成功を返しても、->content() が全てを受け取ってないという事が起こる。

そのほかの環境は弄らずに BitTorrent だけ止めると LWP は正常に送受信できる。
これは何度も再現するのはテスト済。

ちなみに BitTorrent を動かしてるのは WEB サーバーとは別の PC です。
最近は BitTorrent 動かしてないからこういった症状ともおさらばで快適人生♪



>> decoded_content
おぉ〜、こんなメソッドあったんですね。ありがとう!
常々 Encode 呼び出すのめんどくせーって思ってたんで助かる。
0261nobodyさん2011/10/26(水) 02:43:24.74ID:???
>>259
>>257です。
アクセスが出来ないじゃなくて、書き込みができないっていう意味だったんですね。
もっと自分でよく考えてみるべきでした。

-Oオプションを付けて書き込むファイル名を指定したところ上手くいきました。

知恵を貸していただきありがとうございます。
0262nobodyさん2011/10/27(木) 00:59:33.75ID:???
>>244-256
あんなふざけたレスにマジレス返してくれてどうもありがとうございます。
まだ全部は試せてないですが、>>246とか物凄く参考になっています。
perldoc.jpなども読んで、もう少し勉強してみますね。
0263nobodyさん2011/10/27(木) 01:39:37.97ID:???

変数名の前の @、$、% の意味 (* ってのもあるけど、難しいので放置で OK)
変数に代入するときの { }、[ ]、( ) の意味を覚えるだけで、理解度はかなり違うと思います。

あとは perl の自由な書き方に慣れていただくしかw
0264nobodyさん2011/10/27(木) 16:41:18.27ID:???
たまに間違う… そういえばあんまり代入の時に [ ] って使わないなあ。
使ったことがないわけじゃないんだけど。
0265nobodyさん2011/10/27(木) 18:34:30.14ID:???
最近は面倒くさいので $data = [] とか $data = {} とかで済ますこと多いな。
0266nobodyさん2011/10/28(金) 20:00:02.80ID:???
Perlでw3mのようなコンソールアプリケーションを作る方法はあるのでしょうか?
環境はLinuxです。

よろしくお願いいたします。
0267nobodyさん2011/10/28(金) 20:16:08.47ID:???
curses を扱うモジュールはあるみたいだし、できるんじゃね
Python とかのほうが向いてる気はするけど
0268nobodyさん2011/10/30(日) 22:07:34.60ID:???
みなさんモデリングツールでUMLは使ってますか?
もし使ってる方はどのソフト使ってますか?

ttp://hibari.2ch.net/test/read.cgi/tech/1147499933/
↑ここでperlの話題がなく、「perl uml」で検索してもそれらしいものが見つからなかったので質問しました。
UMLを勉強しようと思うのですがどのツールがいいのかもわかりません。。
02692682011/10/31(月) 00:15:05.76ID:???
>UMLを勉強しようと思うのですがどのツールがいいのかもわかりません。。

これはココだとスレ違いですね。
この一文は無視して下さい。
0270nobodyさん2011/11/01(火) 11:30:50.31ID:???
バイナリデータについて質問です。
docomo携帯の太陽のSJIS絵文字コード(F89F)を表示しようとしたのですが、
(1)は表示されて、(2)は単なる文字列になっているようでした。
\x{}といった表記ではバイナリにならないのでしょうか?
また、バイナリにする場合、""での設定やpack()など色々あると思うのですが、
処理が速いのはどの方法になるのでしょうか?

(1)my $sun = "\xF8\x9F"

(2)my $sun = "\x{F89F}"
0271nobodyさん2011/11/01(火) 13:02:20.96ID:???
>>270
http://perldoc.perl.org/perlop.html#Quote-and-Quote-like-Operators
> If the number is 256 (0x100, 0400) or above, Perl interprets it as a Unicode code point
> and the result is the corresponding Unicode character.

http://www.nttdocomo.co.jp/service/developer/make/content/pictograph/basic/

よって iモードの Shift_JIS で "\xF8\x9F" に割り当てられている絵文字を
iモードの UTF-8 のページで出したければ "\xEE\x98\xBE" 。
(Perl用語で言うところの) Unicode 文字列なら "\x{E63E}" 。

参考ページ:
>>2
http://perldoc.jp/docs/perl/5.10.0/perluniintro.pod
http://search.cpan.org/dist/Encode-JP-Mobile/lib/Encode/JP/Mobile.pm
http://search.cpan.org/dist/Unicode-Japanese/lib/Unicode/Japanese/JA.pod
02722702011/11/01(火) 15:15:58.07ID:???
>>271
解決しました。
詳しい説明ありがとうございました。
0273nobodyさん2011/11/01(火) 15:20:02.29ID:???
my $a = {
x => [ 'a', '1' ],
y => [ 'b', '2' ],
z => [ 'c', '3' ],
};

my $b = map{}???

上記で$bに下記のようにセットするにはmapのところをどのように書けばよいでしょうか。

$b = {
x => 'a-1',
y => 'b-2',
z => 'c-3',
};
0274nobodyさん2011/11/01(火) 15:36:36.16ID:???
>>273
$b = { map { $_ => "$a->{$_}[0]-$a->{$_}[1]" } keys %$a };
# or
$b = { map { $_ => join '-', @{ $a->{$_} }[0,1] } keys %$a };
0275nobodyさん2011/11/01(火) 15:59:53.49ID:???
>>273
my $b = { map ref $_ ? join('-', @$_) : $_, %$a };
my $b; %$b = map ref $_ ? "$_->[0]-$_->[1]" : $_, %$a;
02762732011/11/01(火) 16:40:41.18ID:???
>>274,275

解決しました。
回答が早くて助かりました。
ありがとうございます。
0277nobodyさん2011/11/01(火) 17:31:41.93ID:???
サンプルとはいえ$aと$bは安易に使わないほうがいいぞ
02782732011/11/01(火) 17:56:13.77ID:???
use HTML::Template について質問です。
テンプレートファイル内で、「html出力させないコメント」というのは書けないのでしょうか?
例えば下記の#の行はoutputで出力させないといった動作をさせたいです。
もしできないのであれば、使用されている皆さんはコメントを書きたい時、<!-- -->で対応しているのでしょうか?

<html>
<head>
<title>hoge</title>
</head>
<body>
fuga<br>
#コメントを書きたい
</body>
</html>
0279nobodyさん2011/11/02(水) 04:52:21.99ID:???
>>278
無かったはず。

ただし、new()の際にfilterを設定することで、前処理を行うことが出来る。
これを利用して、特定の文字列を置き換える(削除する)ことは可能。
詳細はドキュメントを参照されたい。

HTML::Templateは痒いところに届かないというか、痒み?何それ? って作り方だからなあ。
非PGのデザイナーにテンプレートファイル作りを任せるなら、これくらいじゃないと使ってくれなかったりするがw
0280nobodyさん2011/11/02(水) 07:58:44.36ID:???
>>276
案の定Wikipediaの丸暗記か
0281nobodyさん2011/11/02(水) 10:15:20.86ID:???
>>280
君はまた見えない敵を作って、勝手に戦うのかい?
0282デフォルトの名無しさん2011/11/03(木) 03:59:56.91ID:???
>>280

おみそれいたしました。
丸暗記だと応用が効かなくて行き詰ってしまうことが多いです。
0283nobodyさん2011/11/03(木) 20:45:59.15ID:???
↓こちらのスレで誘導されてこの板に来ました。

Perlについての質問箱 49箱目
http://hibari.2ch.net/test/read.cgi/tech/1319953460/100-102n

Windows 2000、Activeperl 5.8 の環境で、
use Socket;
socket(・・・);
connect(・・・);
な感じでインターネット上のwebサイトからページを取得してるんだけど、
サイトの応答が遅いとき、応答が帰ってくるまでCPU負荷が100%近くになる。

これってどういった原因が考えられますか?
あるいは仕様でしょうか。
PCのスペックはWin2000を使っているというあたりで想像いただける通りかなりしょぼいですが、それにしても負荷高すぎかな、と。

Activeperlのバージョン上げれば直るのかな…
0284nobodyさん2011/11/03(木) 22:20:35.11ID:???
パソコンを変えることができないなら、LANカードを取り替えるか
あるいは追加して、それを使うようにして対処。
今使っているLANカード+ドライバが割込みに対応した作りではない
のでCPU負荷が100%近くになっている。
0285nobodyさん2011/11/03(木) 22:28:37.56ID:???
>>PCのスペックはWin2000を使っているというあたりで想像いただける通りかなりしょぼいですが
端折るな


ちなみに Pentium3 1GHz、ActivePerl 5.12 のうちの環境は sleep 使うと CPU 占有率が 80-90% とかになる。
0286nobodyさん2011/11/03(木) 22:52:53.96ID:???
>>284
LANカードの問題ですか。
ノートだから交換や追加は難しいですね…
>>285
すみません。
Pen4M1.8G(但し1.2G動作)です。

ありがとうございました。
02872852011/11/03(木) 23:57:43.11ID:???
NetBurst か。
デスクトップの Pentium4 ですら同じくロックまで落とすと Pentium3 に負けるからなぁ・・・
ただそれ以外の部分 (チップセットとかね) は Pentium3 世代よりも上だから、CPU はボトルネックとは考えられないか。

古いノートだったら 10Base-T とかの可能性も否定できないよね。

あとアンチウイルスとかスパイウェア関連は外すのも手。
TCP/IP の入出力を監視してたりするので負荷が掛かるのは当たり前だから。

定期的にスクレイピングのために Perl スクリプト走らせてるんだけど、
今見たら 60-80% の CPU 占有率だった。


これ以上はハードとか OS の問題になってきそうなのでスレ違いどころか板違いすらにもなってくるかな?w
その前に色々書いておく。

特に大事なデータが無ければ OS 再セットアップして、アンチウイルスとかスパイウェア関連は入れない。

もし直らなければ、ノートの製造が AOpen や Acer などの安かろう悪かろう的なメーカーでないか確認。
なおかつ使用チップセットが Intel 以外だった場合は遅いのはハードウェアが原因と見て良いかと。

上記以外のメーカーで Intel チップセットの場合は >>284 が書いたとおり LAN カードが怪しいかも?
USB の LAN もあるけど、そもそも負荷が高いので使っちゃだめ。 32bit CardBus が付いてるならその LAN カードを。

これでも駄目なら投げ捨てる。
0288nobodyさん2011/11/04(金) 00:21:01.33ID:???
CD起動のLinuxで同じスクリプトを実行してハードの問題かどうかを切り分けてみる。
02892832011/11/04(金) 08:21:22.37ID:???
>>287
ハードやOSの問題だと板違いですね。
ただ、ブラウザでアクセスしている場合にはそういった問題は発生しないのでperl側の問題という線も捨てきれないのかな、と。

ちなみに、常駐系のソフトは全て停止しても状態は同じでした。
とりあえず、まずはLANカードの線で、何か試す方法がないか検討してみます。

>>288
ちょっとハードルが高いですね。
Linixの知識は全くないので、そこにたどり着くまでの時間が取れそうにないです。

改めてありがとうございました。
02902782011/11/04(金) 11:25:15.47ID:???
>>279
最初に任意のルーチンの割り込みができるんですね。
いまバタバタしてるので時間が空いたらじっくり調べてみます。
ありがとうございました。
0291nobodyさん2011/11/05(土) 11:43:23.98ID:???
>>289
BIOSのIRQの設定も板違いですね。
そうだとするとLANカードを変えても同じことになりそうなので。
0292nobodyさん2011/11/06(日) 08:06:31.58ID:???
$test . '_aiueo'

こうゆう文字列でマッチさせようとしたときに、何も考えずに書けば

/$test_aiueo/

だけど、これじゃ $test_aiueo っていう変数は無いからエラーになるわけで、
$test という変数の直後に半角英数でマッチさせるにはどうすれば良いのでしょうか?
0293nobodyさん2011/11/06(日) 08:12:06.72ID:???
すんません解決しました。

/${test}_aiueo/

こうゆう書き方できるんですね。
$hash={} を %{$hash} とか普段から使ってるクセに、なんですぐに書けなかったんだろう。。。
0294nobodyさん2011/11/06(日) 10:03:01.99ID:???
こういう
0295nobodyさん2011/11/06(日) 12:03:43.66ID:???
作ったスクリプトのどこの部分が処理に時間が掛かってるのか知りたいです。

処理ごとにデバッグプリントすれば可能ですが、非現実的だし、
後々デバッグプリントを消すのも手間なので、Perlでどこの部分で
時間が掛かってるとかのデバッグというか、トレースというか、
そういう事は出来るモジュールなどはあるのでしょうか?

0296nobodyさん2011/11/06(日) 12:30:01.91ID:???
>>295
http://perldoc.jp/docs/perl/5.10.1/perlfaq3.pod#How32do32I32profile32my32Perl32programs63
0297nobodyさん2011/11/07(月) 11:15:35.01ID:???
>>296
ありがとうございます。


#!/usr/bin/perl -d
use Devel::DProf;

で tmon.out を吐かせた後に dprofpp で得たいデータが取れました。
02982782011/11/07(月) 14:03:34.80ID:???
以前html::templateで質問したものです。
>>278の件は解決できました。
ありがとうございました。

もう一つ質問があります。
TMPL_INCLUDEのパスをcgi上でコントロールしたいのですが、下記のようなテンプレートはNGとなっています。

<TMPL_INCLUDE NAME="<TMPL_VAR NAME=incPath>">

そこでfilterを使って表現しようと思うのですが、どのようにすればよいでしょうか?
※cgi内の変数がfilter内のサブルーチンでそのまま使用できるのは確認できています。

my $incPath = './tmpl/inc.tmpl';
my $template = HTML::Template->new(
filename => './aaa.tmpl',
filter => sub{
my $ref = shift;
$ref =~ s/(\$[a-zA-Z0-9_]+)/eval($1)/g; #←ここの置換後の表現が思いつかないのでやりたいことのイメージを書いています。
},
);

--- template ---
<TMPL_INCLUDE NAME="$incPath">
02992982011/11/07(月) 17:02:01.60ID:???
>TMPL_INCLUDEのパスをcgi上でコントロールしたいのですが、

すみません。この一文はわかりづらいですね。
この文は無視してください。
0300nobodyさん2011/11/08(火) 02:25:10.62ID:???
>>298
コメント削除の件は解決して何より。

インクルードファイルを動的に制御するなら、素直に<TMPL_IF>や<TMPL_UNLESS>で分岐させるのが良いのでは。
もしくは、CGI側で別途に読み込んで、<TMPL_VAR>で吐き出すか。

インクルードファフィルのルートディレクトリを指定するだけなら、
new()の時に path を指定することでコントロールできるっぽい。


【余談】
HTML::Templateは条件分岐がマトモに書けないから、可能なら拡張モジュールの利用も考えてみて。
自分は使ったことがないんだけど
http://search.cpan.org/~samtregar/HTML-Template-Expr-0.07/Expr.pm
とかどうだろうか
03012982011/11/09(水) 16:21:33.08ID:???
>>300
もしかして279の方ですかね?
またまたご意見ありがとうございます。

色々試行錯誤しましたが、今回はfilterに下記のようにして対応することにしました。
$replace_ref = {
HENSUU => 'hogehoge',
};

filter{
$ref = shift;
$$ref =~ s|\[\#.*?\#\]||gxms; # [# 〜 #]までをコメント
$$ref =~ s|\[\%\s+([a-zA-Z0-9_]+)\s+\%\]|$replace_ref->{$1}|gxms; # [% 〜 %]を置き換え
}

----- html -----(どんなフォーマットがHTMLに影響ないかわからなかったので変数置き換えはtemplate-toolkitを参考)
<html><body>
[# コメント #]
変数=[% HENSUU %]
</body></html>
---------------

HTML::Template::Exprいいですね。
HTML::Template::Proにも取り込まれてるんで、高速化したい時には置き換えが簡単そう。
HTML::TemplateはIF文が貧弱すぎる。
0302nobodyさん2011/11/15(火) 20:21:14.83ID:???
パターンマッチについてなのですが、

-------------------
<span class="availGreen">在庫あり。</span> <a href="/gp/help/customer/display.html?&nodeId=915624">
在庫状況</a>について<br /> この商品は、<b><a href="/gp/help/customer/display.html?ie=UTF8&nodeId=64
3004">Amazon.co.jp</a></b> が販売、発送します。 ギフトラッピングを利用できます。
-------------------
この文字列(実際には改行は入っていない)から、「Amazon.co.jp」(他の店名になることもある))の部分だけを取り出す為に

if ( $_ =~ />(.*?)<\/a><\/b> が販売/ ) {print $1;}
とすると、
-------------------
在庫あり。</span> <a href="/gp/help/customer/display.html?&nodeId=915624">
在庫状況</a>について<br /> この商品は、<b><a href="/gp/help/customer/display.html?ie=UTF8&nodeId=64
3004">Amazon.co.jp
-------------------
までが拾われてしまいます。

if ( $_ =~ /この商品は、<b><.*?>(.*?)<\/a><\/b> が販売/ ) {print $1;}
とすることにより、目的は達成できたのですが、何故最初のがダメなのかが良くわかりません。

なお、直前の「643004」の部分は場合によって変わるのでキーワードには出来ません。
0303nobodyさん2011/11/15(火) 20:47:48.16ID:???
何故って…
.*?にはタグ(<.*?>)を含まないなんてルールはないし
0304nobodyさん2011/11/15(火) 21:30:08.07ID:???
最小マッチの「最小」の意味を勘違いしてるパターンと予想。
.*? か .* かで影響されるのは "</a></b> が販売" の部分の探し方であって、
マッチすること自体が確定したら最初の ">" の位置は動かない。

関係ないが、この手の情報取得は可能ならまずAPIを検討すべき。
泥臭くスクレイピングするとしても、よほど高速性を重視するとかでなければ
正規表現じゃなくてTreeBuilderとかでDOMをパーズするほうが安全。
0305nobodyさん2011/11/16(水) 00:15:29.63ID:???
>>304
ありがとう。
最初の「>」で拾ってしまうんですね。

高速性の必要なものではなく、いくつかの商品の価格変化をログ取ってるだけなので、
API利用するところまでは考えてません。手続きめんどいので。
0306nobodyさん2011/11/16(水) 06:46:36.29ID:???
>>305
拾いたい箇所が1ファイルに1箇所くらいで構造も単純ならパターンマッチングの方が
手っ取り早いよね。
でも構造が繰り返しだったりややこしかったりする時はWeb::Scraperとか便利よ。

>>304
パーズ? パース? ← parse
0307nobodyさん2011/11/16(水) 07:50:11.05ID:???
考えるの面倒だからという理由で、モジュールに丸投げする底辺でゴメンナサイ
0308nobodyさん2011/11/16(水) 09:59:12.27ID:???
そのためのモジュールでしょ 無問題
03093042011/11/16(水) 10:04:04.24ID:???
ありゃ。smooth(ズ)→スムース みたいなもんで英語では parz って発音するものだと思い込んでたからそれに合わせてたわ。
調べてみたらイギリス英語系の辞書だとパーズだけど、アメリカ英語でパースが一般的みたいだからそっちのほうがいいや。サンクス
0310nobodyさん2011/11/16(水) 16:16:46.49ID:???
>>309
>イギリス英語

へー。良いことを知った。
0311nobodyさん2011/11/16(水) 16:34:39.13ID:???
本当だ。
2つ発音されるね。

parseの意味 - 英和辞書 - goo辞書
http://dictionary.goo.ne.jp/leaf/ej3/61513/m0u/parse/
0312nobodyさん2011/11/16(水) 16:52:26.25ID:???
そうか。どっちもありなんだ。
勉強になったぜ。
0313nobodyさん2011/11/16(水) 23:26:19.41ID:???
テキストファイルから3行だけほしいときって、1行で記述することってできますか?

今は for で回して push してるんだけど、
@lines = <$fh> x 3;
みたいな感じで書けたら落ですよね。。。
0314nobodyさん2011/11/17(木) 00:05:31.82ID:???
>>313
#!/usr/bin/perl -w
use strict;
my @line = (scalar <DATA>, scalar <DATA>, scalar <DATA>); # 幾つ?
print @line, "---\n"; seek DATA, -12, 1; @line = ();

@line = map scalar <DATA>, 0..2; # 0から2とは?
print @line, "---\n"; seek DATA, -12, 1; @line = ();

push @line, scalar <DATA> while @line < 3; # 意図が分かりやすい
print @line;

__DATA__
foo
bar
baz
quux
0315nobodyさん2011/11/17(木) 00:27:12.12ID:???
やっぱ、なんかしらで回すしか無いですよね。
ありがとうございました。
0316nobodyさん2011/11/17(木) 00:48:38.68ID:???
>>315
ループを避ける事自体が至上命令ならば >>314 の1番目か
$/ = \64; # 充分なサイズのバッファ
my @line = <DATA> =~ /^(.*\n)(.*\n)(.*(?:\n|\z))/;
0317nobodyさん2011/11/17(木) 00:53:27.15ID:???
@line = (<DATA>)[0..2];
0318nobodyさん2011/11/17(木) 09:42:10.49ID:???
至上主義ってわけじゃないんだけど、ループの中で特に処理をするわけじゃないから
1行で簡潔にできたら嬉しいよね〜

っていう程度です。
0319nobodyさん2011/11/18(金) 00:09:48.76ID:???
ループを決して書こうとしない部下を思い出した。
そいつは自分自身がループして同じ内容を必要な行数分タイプしてたっけ。
■ このスレッドは過去ログ倉庫に格納されています