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

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

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2006/06/26(月) 00:46:38ID:???
Perlのコーディングで困ってる人のスレです。

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

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

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

過去ログやお勧めサイトは >>2-10
03533512006/07/09(日) 15:45:39ID:???
>>352
># TMTOWTDI
そだね。
0354nobodyさん2006/07/09(日) 16:19:00ID:???
こういうのを見てしまうとPerlに戻りたくなるなぁ
制御構文の後置って書いていて気持ちいいんだよな
0355nobodyさん2006/07/09(日) 16:29:17ID:Grc/Miyg
質問です。

以下のようなハッシュと配列があります。

my %sex = (
'm' => '男性',
'f' => '女性',
);

my @list = ('name','age','sex','mail','addr', ・・・);


プログラム中で、
while (my($key,$val) = each(%sex)){
 ・・・
}

という処理を行いたいのですが、%sexの'sex'という文字列を、@listから拾いたいのです。

while (my($key,$val) = each(%{$list[2]})){
 ・・・
}

というふうに。
もちろん上記の例では「ハッシュではありません・・・」という意味のエラーが出るのですが、
やりかたがわからず困っています。

each(eval ('%' . "$list[2]")

でもやっぱりダメで、他に考え付きません・・・
よろしくお願い致します。
0356nobodyさん2006/07/09(日) 16:39:01ID:???
my @list = (\%name,\%age,\%sex, ・・・); これじゃあかんのかいな?

ってか普通は %sex とかを $hash->{sex} = {}; とかってやる気がする。

ちなみに eval でやるなら
each(eval ('%' . "$list[2]") → each(eval ("\\%$list[2]") こうじゃね。
0357nobodyさん2006/07/09(日) 16:46:51ID:???
\ 多いて orz
0358nobodyさん2006/07/09(日) 16:46:54ID:???
eval "each %$list[2]"
03593552006/07/09(日) 19:33:47ID:???
>>356
配列@listには、"配列やハッシュに使う「名前」"だけを格納してるのです。。

>>358
evalの使い方を間違えていたのですね。
ありがとう。その例でできました。
0360nobodyさん2006/07/09(日) 20:03:39ID:???
>>359
>配列@listには、"配列やハッシュに使う「名前」"だけを格納してるのです。。
どういう経緯でそうなったかは知らないけど、
eval使いまくりで効率悪くなる事この上ないなぁ。

my %var = (
 'sex' => {
  'm' => '男性',
  'f' => '女性',
 },
 ...
);

みたいにして
each %{$var{$list[2]}}
とすると、eval使わなくていいけど。
0361nobodyさん2006/07/09(日) 20:04:15ID:???
どうしてこう変数名を使ってなにかをしたがる奴が多いのだろうか。
デバッガ作るんでもなけりゃ名前をキーにしたハッシュにしとけよ。
0362nobodyさん2006/07/09(日) 20:39:33ID:???
てぃむどぅでぃはいいけど、せめて use strict 通るのにしたいね。
0363nobodyさん2006/07/10(月) 09:14:03ID:???
perlでサービスというか常駐プログラムを作りたいんだが
メモリの取得とか開放とか 変数使ったときの内部の挙動が
いまいち心配なのですがどうしたらよいでしょうか
0364nobodyさん2006/07/10(月) 09:41:10ID:???
>>363
perlのGCはリファレンスカウントなので循環参照を作って使い
捨てるとメモリリークになる。これに注意すれば無限に太り続ける
ことはないだろう。

perlは基本的にosからとったメモリは返さないので、一度でも大量に
メモリを使うと太ったままになる。それが困るようならたまにexecする
ぐらいしか手はない。

例外もあるがくわしくはperlfaq3の

How can I free an array or hash so my program shrinks?

参照。
0365nobodyさん2006/07/10(月) 16:54:29ID:kBFNwS+A
2つの配列に同じ要素を代入したいんですが
pushで複数の配列に同時に要素を代入する方法ってありますか?
0366nobodyさん2006/07/10(月) 17:07:07ID:???
>>365
pushにそんな機能は無い
0367nobodyさん2006/07/10(月) 17:18:03ID:kBFNwS+A
>>366
ありがとうござました。
おとなしく、2つ目の配列に1つ目の配列を代入します。
0368nobodyさん2006/07/10(月) 17:46:11ID:???
それより同じ配列を二つ用意しない方法を考えた方がいい気がするけど
0369nobodyさん2006/07/10(月) 18:08:23ID:kBFNwS+A
>>368
数字を、片方はそのまま(データ処理用)、
もう片方はコンマ付き(ブラウザ表示用)、
と分けようとしたとき、その過程でどこかに
同じ配列を用意しないといけないと思っていました。
そうしなくても良い方法ってありますか?
0370nobodyさん2006/07/10(月) 18:14:45ID:???
「同じ要素」 って言ってなかったっけw
0371nobodyさん2006/07/10(月) 18:16:43ID:???
ブラウザ表示する時にはじめてカンマつけて出力すれば?
どうせカンマ付きはそこで使い捨てになるんだろうし。
同じ配列2つだと整合性の問題もある。
0372nobodyさん2006/07/10(月) 18:24:39ID:kBFNwS+A
    @       A        B       C
数字のデータ → 配列A → 素のデータ  →   処理
         → 配列B → コンマ付きデータ → ブラウザ出力

という流れを想定しての質問でした。

>>370
確かに結果的には別の要素になりますが、その過程(Aの時点)では
同じ要素を入れる必要があると考えていたので、その局所的な点から
「同じ要素」と言ってしまいました。誤解を与えたならすみません。

>>371
ブラウザに表示するのは1度ではないので、その都度コンマを付けるより
初めから別に配列のデータを作って代入した方が良いかと思っていました。
整合性の問題については具体的には良く分かりません。
0373nobodyさん2006/07/10(月) 18:27:23ID:???
>>372
(3) の時点で配列のコピーつくればいいんじゃ?
var Array2 = Array1.concat(); とかして
0374nobodyさん2006/07/10(月) 18:33:57ID:???
>>372
>整合性の問題については具体的には良く分かりません。
途中で素のデータの方に変更がかかると
コンマ付きの方と値がズレるかも、ということ。
素のデータを更新したら、その都度、コンマ付きの方も更新しないといけない。
そういう心配をするなら、一つにしといた方が間違いが無い。
0375nobodyさん2006/07/10(月) 18:50:46ID:kBFNwS+A
>>373
(2)の段階で配列を2つ作ることと
(3)の段階で配列のコピーを作ることとの違いが分かりません。

>var Array2 = Array1.concat();
こういうのは見たことがないんですが、
配列のコピーというのはそういったテンポラリファイルとしてコピーする
モジュールか何かがあって、それを使うということでしょうか?

>>374
ご説明ありがとうございます。
配列に代入した後にデータを変更することはないので
その点については大丈夫です。
ただ、そういう考え方は重要ですね。
03763632006/07/10(月) 18:52:56ID:???
>>364
ありがとうございまんこ
変数はローカル変数でも消費しちゃうのかな
とりあえず、perlでデーモンはいったんあきらめてみます
0377nobodyさん2006/07/10(月) 19:12:46ID:???
>>375
> 配列に代入した後にデータを変更することはないので
今の処理ではそうでも、何か拡張したときに変更するかも知れない。
データは1つだけ持っておき、出力時に変換関数を通すほうが安全。

同一データを変換する処理が数百回にも及ぶため、変換後のデータをキャッシュしておきたい、
というような要求に見えるが、安全性からはオブジェクトにして、データへの変更時には、
キャッシュも必ず更新されるようコーディングすべき。
0378nobodyさん2006/07/10(月) 19:41:21ID:kBFNwS+A
>>377
アドバイスありがとうございます。

例えば、ブラウザに直接表示される部分はコンマ付きの値を
同時にフォームのhiddenでコンマ無しの素の値を、それぞれ置いておく
と言った場合には、局所的にせよ、やはり同じ配列を用意して
片方だけをコンマ付きにする必要があると思うんですが、
どうでしょうか?
0379nobodyさん2006/07/10(月) 19:46:27ID:???
もうどっちでもいいよ、君の好きなようにすればいい。
0380nobodyさん2006/07/10(月) 19:51:23ID:???
なんで一時的にしか使わないコンマ付きの値を、
配列全体に渡って作ろうとしているのか、そこが不明。

どうせ表示して終わりなんでしょ?
だったら、テンプレートにフィルタかけて、
表示側だけコンマ付きにすることもできるのに。

まぁ重複管理したければどうぞ。
0381nobodyさん2006/07/10(月) 20:01:11ID:???
初心者スレとは思えない厳しさだな。おまえらw
0382nobodyさん2006/07/10(月) 20:11:58ID:kBFNwS+A
>>379
はぁ・・・そうですか。
気分を害されたようでしたらすみません。
別段口答えしようというわけではなく、
指摘されたようなデータの保持の仕方は
理想的で、常にそうあるよう心掛けるべきだとは思いましたが、
どんな場面でも適用できるのか疑問に思ったので
しつこく質問してしまいました。
すみませんでした。

>>380
>なんで一時的にしか使わないコンマ付きの値を、
>配列全体に渡って作ろうとしているのか、そこが不明。
例えば、「数字をフォームに入力し、その数字について確認する
確認時には見やすいようにコンマ付けされた数字をブラウザには表示する
しかし、それとは別にhiddenで素の数字を置いておく」
といった場合のやり方をするためには、同じ配列を用意して
片方の配列のみコンマ付け仕様にする、という方法しか思いつかなくて
そうしていました。
ちなみに、配列内全てが入力された数字の情報なので、配列全体に渡って
コンマ付きの値を作る必要があるという流れになりました。

>だったら、テンプレートにフィルタかけて、
>表示側だけコンマ付きにすることもできるのに。
この方法については知りませんでした。
具体的にどういうことかはよく理解できませんが、
これ以上の質問はスレ汚しになりそうですし
お怒りを買いそうなので、これにて失礼します。

レス下さった方々ありがとうございました。
気を悪くされた方々、悪意はありませんでした。すみませんでした。
0383nobodyさん2006/07/10(月) 20:24:53ID:???
>>382
379だけど、
別に気分害したわけでもなく、単にどっちでもいいと思っただけw
好きなように書かないと楽しくもないし、そっちのがお手軽なら、そうすればいいんじゃね? みたいな。
せっかく perl なんだから、1つの方法にこだわることないし。
>>380 とかだって、よりいいやり方もあるよ、って示しただけだしね。
0384nobodyさん2006/07/11(火) 00:36:18ID:???
要は保存用の配列と表示用の配列ってことでしょ?

メモリ上の配列を弄ってもデータファイルには影響ないのだから、データ保存完了後に
好き勝手弄ればいい
0385nobodyさん2006/07/11(火) 10:15:27ID:???
mod_perlか何かで、カンマ付きの値もずっと持ち回るなら、
あるいはパフォーマンス上、別データとして保存する利点もある。

しかし、同一の値を1回だけ出力するという今回の質問では不要。
元データだけ持っておき、出力時に変換すれば十分。
というか、メモリの無駄使い。
0386nobodyさん2006/07/11(火) 10:33:29ID:???
配列や変数を見直すより、出力部分を考えたほうがいい。
大抵はテンプレートファイルを読み込んで
決めておいたタグ部分を変数に置換するものだと思う。
その時に「カンマをつけるタグ」を別途用意しておいて
カンマつける関数かまして置換すればいいと思う。
自力で考え出した時俺は天才かと思ったwwwナツカシス
0387nobodyさん2006/07/11(火) 12:28:46ID:???
Template Toolkit用のプラグインで

Template::Plugin::Comma - TT Plugin to commify numbers

ってのがまさしくそういうの。CGIじゃTTは重いかもしれんけどね。
0388nobodyさん2006/07/11(火) 12:34:16ID:???
TT使ったことがあれば出力時に処理すればいいだけだとわかる
モジュール使わずに自分で書いてるとなかなか思いつかないかもね
俺も最初は変数コピーしてカンマつけてその変数を出力してた
>>386みたいにすればテンプレートをいじるだけでOKだから管理が楽
0389nobodyさん2006/07/11(火) 15:26:39ID:???
var Array2 = Array1.concat();
で、なんでだれもココ突っ込まないんら?
0390nobodyさん2006/07/11(火) 15:33:00ID:???
>>389
シッ! 見ちゃいけません!
0391nobodyさん2006/07/11(火) 15:38:05ID:???
>>389恐ろしい子っ!!!
0392nobodyさん2006/07/11(火) 19:27:03ID:D6pM+gvD
流れぶったぎってスマソ

6桁の数字の連続060711とあったら
$yaer = 06;
$mon = 07;
$day = 11;
というように分けるにはどうすれば良いんでしょ?
06.07.11みたいに区切り入れてsplitするしかない?
0393nobodyさん2006/07/11(火) 19:28:51ID:P82+nFT5
my $temp = qq|Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)|;
print @{[split /;/,$temp]}->[1];

これってどういう理屈でしょうか。
splitがリストを返してきてそれを一旦無名リファレンスにしてますよね?
で、あとはそれをデリファレンスだけですが。

う〜ん・・・無名のデリファレンスってこんなのだっけなぁ
03943932006/07/11(火) 19:30:40ID:P82+nFT5
print [split /;/,$temp]->[1];

やっぱり普通はこうですよね。
で、両方できるみたいだけど。。。
初めのやつはどんな理屈なんでしょうか。
03953932006/07/11(火) 19:32:35ID:P82+nFT5
もしかして初めのやつは

[split /;/,$temp] これで無名配列リファで
{[split /;/,$temp]} これでさらに無名ハッシュリファにしてますか??

それでハッシュの中に入ってる配列のリファのデリファをするのに
print @{[split /;/,$temp]}->[0];
ってなるのかなぁ。
でもなんで初めに%じゃなくて@になるんでしょう
0396nobodyさん2006/07/11(火) 19:38:55ID:???
>>392
my($year, $mon, $day) = unpack("A2A2A2", "060711");
0397nobodyさん2006/07/11(火) 19:39:59ID:???
>>982
my @date = ( '060711' =~ /(\d{2})/g ) ;
0398nobodyさん2006/07/11(火) 19:47:57ID:???
>>393
>print @{[split /;/,$temp]}->[1];
多分、それを書いた人はデバッグしてる時に
print "@{[split /;/,$temp]}";
↑こんな感じでsplit後のデータを表示してた。

配列リファレンスのデリファレンスをすると、ダブルクォートの中に入れられる。
その名残が残ってるだけだと思う。
別に深く気にする事はない。
03993922006/07/11(火) 19:52:07ID:D6pM+gvD
>>396-397
サンクル!
unpackって関数知らなかった。色々使えそうだわいわい。
正規表現ってホント色んなことできるなぁ。
やり方は全然思い付かないけど・・・。
04003932006/07/11(火) 19:59:25ID:P82+nFT5
>>398
なるほど。HTMLに埋め込む時の手法ですね
@{[]}とか${\[]}だったかな。

>配列リファレンスのデリファレンスをすると、ダブルクォートの中に入れられる。
これはどういうことでしょう。

あ、つまりHTMLの中に入れられるみたいな意味ですね。
納得です。
04013932006/07/11(火) 20:08:51ID:P82+nFT5
すみません、久しぶりに来たのでもう一つ質問したいのですが。
宜しくお願いします。

アクセス解析を自分で遊びで作ったのですが、たまにアクセスから1分以内とかのだけみたいときがあります。

sprintf "%04s%02s%02s%02s%02s%02s",sub{shift()+1900,shift()+1,@_}->([gmtime(time+32400)]->[5,4,3,2,1,0]);

このフォーマットで、作ってる現在時間と記録されてる過去の時間の時間的比較ってどうやればいいですか?
今は1分なら100とかでやってしまてるのですが。

変換関数とかあるのでしょうか?mistyでは見つかりませんでしたが。
04023932006/07/11(火) 20:20:59ID:P82+nFT5
モジュールがあるようですね。datetimeっていう。
使わない場合はやはり簡単ではないようで。
数学の世界ですねきっと。
0403nobodyさん2006/07/11(火) 20:35:09ID:???
>>401
待て待て待て
そのフォーマットなら単純に文字列比較するだけで良いはずだが。

my $limit = sprintf "%04s%02s%02s%02s%02s%02s",sub{shift()+1900,shift()+1,@_}->([gmtime(time-60)]->[5,4,3,2,1,0]);
if ($limit lt $date) { }
で一分以内になるはず。試してないが

後、この場合じゃ無駄だがgmtimeの逆をする関数ならTime::Localにある
ttp://search.cpan.org/~drolsky/Time-Local-1.12/lib/Time/Local.pm
0404nobodyさん2006/07/11(火) 20:42:15ID:???
use POSIX qw(strftime); # とかなんとか
でいろいろ使えると思うけど。1900足したりしなくていいし。
0405nobodyさん2006/07/11(火) 20:44:44ID:???
まさに「データファイルを見直せ」の典型ですね
04063932006/07/11(火) 21:22:41ID:P82+nFT5
>>403
おお!
モジュールを使うと、フォーマットやら細かい部分が変わってしまって
色々手を入れないといけなくなりそうだったので嫌だったのですが。

盲点でした。60秒前の設定で作り直せばよかったんですね。
それもltなんて知りませんでした。
いまさらltまで発見させてもらって最高です。
04073932006/07/11(火) 21:24:30ID:P82+nFT5
ところで
ltと>ってどうやって使い分けるんですか?

そもそも文字列を数値比較するなら>,==とかでいいとおもうのですが。
0408nobodyさん2006/07/11(火) 21:29:11ID:???
数値比較しかないと、数値じゃない文字列の比較ができないことになる
04093932006/07/11(火) 21:37:58ID:P82+nFT5
>>408
???
a ne a
はわかるのですが、
1 lt 1
がわからないのです。
1 > 1とどういう差があるのか・・・
0410nobodyさん2006/07/11(火) 21:42:41ID:???
>>409
だからなんで数値だけの文字列と比較するんだよ。

"hoge" と "1234" 比較して、"hoge" の方が大きい事を
判断したい場合もあるだろうが。
数値比較しか無いなら、"hoge"はいつでもゼロになる。
04113932006/07/11(火) 21:48:06ID:P82+nFT5
>>410
hogeに数字を与えるのですか?
hageとも違う数字を?

ちょっと実験してきます。
04123932006/07/11(火) 21:50:40ID:P82+nFT5
!!!!!

print "左辺の方が小さいです。" if "hage" lt "hoge";
print "左辺の方が小さいです。" if "hoge" lt "hage";

どうやら"hage"の方が小さいようです・・・・
どうなってるのですか?これ。
0413nobodyさん2006/07/11(火) 22:06:01ID:???
a lt o だから
0414nobodyさん2006/07/11(火) 22:06:29ID:???
簡単に言えば、
・一文字目は両方ともhで同じ('h' eq 'h')。
・二文字目はaよりもoのほうが後にある('a' lt 'o')
ので、hageよりもhogeのほうが大きい、と判断される。
この一文字一文字の比較はバイト列として行われるから、詳しくはASCIIコード表をじっくり眺めてくれ。

ちなみに、数値しか入ってこないはずの日時の比較になぜ文字列比較をしたのかと言うと。
この場合はまだ良いんだけど、後数桁増えた場合、数値として扱うと誤差が発生するため、固定長の場合は習慣的に。
> print 20060711213959123456;
2.00607112139591e+19
> print 20060711213959123456 < 20060711213959123455
1
0415nobodyさん2006/07/11(火) 22:24:42ID:???
よくわからんがごちゃごちゃ変なことやらずにはじめからunix timeで(timeの戻り値をそのままで)
保持しておけば比較も簡単だと思うのだが、なぜわざわざ話をややこしくしたがる奴が多いの
だろうか。
0416nobodyさん2006/07/11(火) 22:51:13ID:???
DARK SIDE OF TIMTOWTDI
0417nobodyさん2006/07/11(火) 23:02:30ID:???
初心者スレだからあえて突っ込こんどく。

ほんとに誤差がでるの?@5.8.8
-------------
$\ = "\n" ;
print 20060711213959123456;
print 20060711213959123456 > 20060711213959123455
-------------
2.0060711213959e+20
1

自分の環境に合わせて、lt を使うかどうか判断しましょう
0418nobodyさん2006/07/11(火) 23:07:10ID:???
>>415 に同意
書くときに localtime なりすればいいわけで、
これならたとえ 西暦 から ともだち暦 に変わったってデータの変更とか必要ないしな。
0419nobodyさん2006/07/11(火) 23:09:27ID:???
lt知らなかったけど、可読性が下がる方向性しか見えてこないw、
0420nobodyさん2006/07/12(水) 00:23:20ID:qvG7JsXw
perl初心者です。
今CGIを制作しているのですが、正規表現でおもいっくそ躓きましたorz

例えば「$nameが5文字以上、100文字以下でなければエラーを実行する。」
みたいな感じに「$name」に文字制限を掛けたいのですが・・・。
よろしくお願いします。
0421nobodyさん2006/07/12(水) 00:31:07ID:cb+ZHaYE
length($name)
0422nobodyさん2006/07/12(水) 00:35:00ID:qvG7JsXw
>>421
すいません。ありがとうございます・・・。
しかし、悩んでいるのはその先なんです・・・。それをどのように正規表現のパターンにはめればよいか・・・。
0423nobodyさん2006/07/12(水) 00:40:55ID:???
正規表現じゃなくて、length() を使って条件分を書けば良いだけ
0424nobodyさん2006/07/12(水) 00:42:25ID:???
>>420
正規表現で何がしたいのか書いてなくね?
0425nobodyさん2006/07/12(水) 00:54:54ID:qvG7JsXw
>>424
「5文字以上、100文字以下」であることを調べたいと思ってるんですが・・・ orz
0426nobodyさん2006/07/12(水) 00:57:04ID:???
unless (5 <= length($name) and length($name) <= 100) {
&error;
}
0427nobodyさん2006/07/12(水) 01:01:22ID:???
翻訳します。

質問:
5文字以上100文字以下の文字列にマッチする正規表現が書きたい
回答:
出来無くないけど正規表現の使い方間違えてるよ
0428nobodyさん2006/07/12(水) 01:03:57ID:???
unless ($name =~ /^.{5,100}$/) {
&error;
}
0429nobodyさん2006/07/12(水) 01:06:52ID:w3I1i8Fs
print 2+4*3/2-1; # 7
print (2+4)*3/2-1; # 6(8が正しいはず)
print int((2+4))*3/2-1; # 8
となるのは何故でしょうか?
04304202006/07/12(水) 01:13:25ID:qvG7JsXw
あぁ・・・もう・・・
こんな低レベルな質問に・・・本当にありがとうございました orz
0431nobodyさん2006/07/12(水) 01:13:29ID:cb+ZHaYE
print (2+4)         *3/2-1;
0432nobodyさん2006/07/12(水) 01:17:09ID:???
納得しましたorz。ありがとうございました。
0433nobodyさん2006/07/12(水) 01:28:20ID:???
$hoge = "a,b,c,d,e,f,g,h,................";
と「,」で区切られた文字列があるとして
その中の冒頭部分のいくつかの要素が欲しいとき
どうするのが一番メモリ食わずに済みますか?
例えば、上の文字列からbとcとdが欲しい場合、
(undef,$hage1,$hage2,$hage3,undef) = split(/,/,$hoge);
とするのがベストなんでしょうか?
0434nobodyさん2006/07/12(水) 01:38:13ID:???
まぁ、しょうがないんじゃないの?
あとはsplitした結果の配列スライスを取るしかないね。
正規表現は処理として重いし。
データが絶対に1文字なら、substrで切ってからsplitするとか。

データが5000とかあって、3番目から100個取りたいとかいう事でなければ、
あまりメモリを気にしてもしょうがないよ。
perl使ってる時点で、かなりのメモリを喰ってる訳だから。
04354332006/07/12(水) 01:46:55ID:???
>>434
ありがとうございます。
多少のことなんか気にせずバリバリ書く方が気楽なんですけどね。
省メモリに凝りだすと、ついついつまらないことまでも気になって眠れませんw

ちなみにものすごくどうでも良いことだとは思うんですが
(undef,$hage1,$hage2,$hage3,undef) = split(/,/,$hoge);

(undef,$hage1,$hage2,$hage3,) = split(/,/,$hoge);
って、あらゆる点から見て全く同じ処理という解釈で良いんですかね?
0436nobodyさん2006/07/12(水) 01:52:13ID:???
小手先だがsplitに第3引数を与えて余計な分解はしないようにするといいよ

(undef,$hage1,$hage2,$hage3,undef) = split(/,/,$hoge,, 5);
0437nobodyさん2006/07/12(水) 02:05:31ID:???
>>435
質問の答えじゃないですが
perldoc -f split
で第3引数のLIMITを見てみて。単純にsplitするよりは効率いいかも。
04384332006/07/12(水) 02:18:09ID:???
>>436-437
なるほど、どこまで読み込むかの範囲指定できる引数を割り当てられるんですね。
って、以前にsplitの項を本で読んだときに絶対目にしてるはずなんだけどなぁ。
実際に使わないと身に付かない体質なのか・・・。
これは付けておくに越したことはないですね。可読性の点からも悪くないですし。
即、該当箇所全てに割り振らねば!
ありがとうございました!

undefで値を捨てるのと、そもそも値を未定義(?)にしておくのと何か違いがあるのか
分かる方いらっしゃいましたら、お暇なときにでも教えて下さい。
0439nobodyさん2006/07/12(水) 02:44:06ID:???
>>435
>ちなみにものすごくどうでも良いことだとは思うんですが
>(undef,$hage1,$hage2,$hage3,undef) = split(/,/,$hoge);
>と
>(undef,$hage1,$hage2,$hage3,) = split(/,/,$hoge);
>って、あらゆる点から見て全く同じ処理という解釈で良いんですかね?

上はそのまま。
下は、
(undef,$hage1,$hage2,$hage3) = split(/,/,$hoge);
に最適化される。
0440nobodyさん2006/07/12(水) 02:56:50ID:???
左辺にundef置いても警告されないんだ。いい事聞いちゃったw
0441nobodyさん2006/07/12(水) 04:55:16ID:???
どうでもいいがundef 書くくらいだったら
my ( $hage1,$hage2,$hage3) = ( split/,/,$hoge)[1,2,3] ;
てスライス使わない?


0442nobodyさん2006/07/12(水) 09:45:38ID:???
>>438
> これは付けておくに越したことはないですね。可読性の点からも悪くないですし。
> 即、該当箇所全てに割り振らねば!

何も考えずに即値をばらまくと後できっと忘れます。やるならコメント推奨。


> undefで値を捨てるのと、そもそも値を未定義(?)にしておくのと何か違いがあるのか
> 分かる方いらっしゃいましたら、お暇なときにでも教えて下さい。

undef って書かなくていいので、楽ちんな上にプログラムサイズを小さくすることができます。
いや正直「そもそも値を未定義(?)にしておく」が、どういう操作を指しているのか分からないので分かりません。
0443nobodyさん2006/07/12(水) 10:47:13ID:???
>>420
日本語が含まれるのかどうかについて誰も触れていないんだが?
0444nobodyさん2006/07/12(水) 11:35:39ID:???
>>441の方法が普通だよな。
(undef,$hage1,$hage2,$hage3) = split(/,/,$hoge);
なんて酷いの始めてみた。
0445nobodyさん2006/07/12(水) 11:38:48ID:???
特に酷いとは思わない俺ガイル
0446nobodyさん2006/07/12(水) 11:50:40ID:???
>>444
undef を左辺に置く手法は、何番目の要素をそれぞれ拾い、捨てているのか視覚的に分かりやすいというメリットもある。
リストの要素数が小さく、かつ一定である場合には特に。
0447nobodyさん2006/07/12(水) 11:55:26ID:???
ダミーを用意しなくてもいい
スライスしなくてもいい
を考えて、warningが出ないなら有用だと思うが
04484412006/07/12(水) 12:13:35ID:???
軽い違和感を感じただけだから、>>446-447 の意見で納得した。
まあ機会があれば使うかもしれん。
>>393
>print @{[split /;/,$temp]}->[1];
の方は「 split のケースでは」一生使うことはない。

0449nobodyさん2006/07/12(水) 14:25:53ID:???
プチ天狗になりそうだった自分を戒めてくれる流れだわ。
0450nobodyさん2006/07/12(水) 16:11:36ID:x2NzMLn/
foreach $line (@log) {
 foreach $keyword (@keywords) {
  if ( index($line, $keyword) >= 0 ) {
    push (@result, $line);
    last;
  }
  }
}

こーんな感じで検索してるんだけど、
@keywordsの中身がHitしても次の行に行ってくれない、
というか@keywordsの複数の中身がhitすると同じ行が何回もpushされちゃう。
なんでなんでしょうか?
0451nobodyさん2006/07/12(水) 17:18:49ID:???
>>450 のループ自体は正常に結果を吐くので他の要因だと思われ。
つーか index をそう使うの初めて見た
0452nobodyさん2006/07/12(水) 20:58:47ID:???
grep
■ このスレッドは過去ログ倉庫に格納されています