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

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

■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん2005/05/25(水) 06:36:28ID:PVpWgcdf
Perlのコーディングで困ってる人のスレです。

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

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

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

過去ログやお勧めサイトは >>2-10
0583nobodyさん2005/06/25(土) 15:09:40ID:???
>>582
ttp://perldoc.jp/docs/perl/5.8.1/strict.pod
0584nobodyさん2005/06/25(土) 15:20:19ID:???
>>583
!
use strictしたところ、配列の変数名が間違っていることに気づきましたorz
ありがとうございました。
# rootさんのソースなのに…
0585nobodyさん2005/06/25(土) 15:29:33ID:???
んなもん誰にでもミスはあるさ
05865762005/06/25(土) 20:03:10ID:???
ありがとうございました。

>>579のソースが私的にわかりやすかったので、使わせていただきます。
0587nobodyさん2005/06/26(日) 03:21:28ID:???
教えて下さい
レンタルの日記を借りて、スキンを使ったのですが画像を投稿出来ないので
自分でスキンのタグを変更可能してもおkと書いてあったので
画像を無理やり出すイレギュラーってのをやりたいのですが
何を挿入していいか分かりません・・。
画像投稿可版・不可版(同スキン)を両方DLしてソースを見比べたのですが
どうしても分らず、ぐぐっても分りませんでした・・。
どんなタグ?をどの辺りに挿入すればいいのか教えてもらえませんか・・?
よろしくお願いします。
(どこで聞いていいか分からなかったのでスレ違いだったらすみません・・)
05885872005/06/26(日) 03:24:35ID:???
すみません、初心者で検索かけたのでスレ違いに今気づきました・・。
他で聞いて来ます。
申し訳ありませんでした・・。
0589nobodyさん2005/06/26(日) 23:02:23ID:3dNr93yG
下記のSOCKET通信プログラムにて画像を取得しているのですが、サーバによって
print SOCKET "User-Agent: " . $browser . "\n";
で止まってしまうものがあるようです。

モジュールが入っていることは確認できているのですが、もしも
なにかお気付きの点等ございましたらご教示いただきたく思って
おります。どうか宜しくお願いいたします。


use Socket;
use FileHandle;
my $ip = inet_aton($host) || die "host($host) not found.\n";
my $sockaddr = pack_sockaddr_in($port, $ip);
socket(SOCKET, PF_INET, SOCK_STREAM, 0) || die "socket error.\n";
connect(SOCKET, $sockaddr) || die "connect $host error.\n";
autoflush SOCKET (1);
binmode(STDOUT);
print SOCKET "GET $directory$filename HTTP/1.1\n";
print SOCKET "User-Agent: " . $browser . "\n";
print SOCKET "Host: " . $host . "\n";
print SOCKET "Connection: close\n\n";
while(<SOCKET>){
m/^Content-Type: ([^\r\n]+)/i && print "Content-Type: $1\r\n";
m/^Content-Length: ([^\r\n]+)/i && print "Content-Length: $1\r\n";
m/^\r\n$/ && last;
}
print "\r\n";
while(<SOCKET>){
print $_;
}
close(SOCKET);
0590nobodyさん2005/06/26(日) 23:41:10ID:???
>>589
なんで
> print SOCKET "User-Agent: " . $browser . "\n";
で止まってるって思ったの?
0591nobodyさん2005/06/27(月) 01:10:18ID:???
俺もそれ聞こうと思ってた
0592nobodyさん2005/06/27(月) 01:29:08ID:???
perlのコーディングを楽にするために、
HTMLの記述をprint "〜"に変換する作業を一括で行うソフトウェアを探しているのですが、そのようなソフトはありますか?

例えば、
<a href="abc.html">ABC</a>
を
print "<a href=\"abc.html\">ABC</a>"
と変換できるものです。
0593nobodyさん2005/06/27(月) 01:37:26ID:???
なんていうか、ヒアドキュメントとかqqとか知ってる?
0594nobodyさん2005/06/27(月) 01:44:19ID:???
ガーン・・・

そんな方法があったんですか・・・・。今日はじめた初心者だったのでごめんなさい。
>>593さんありがとう('A`)
0595nobodyさん2005/06/27(月) 01:46:16ID:???
>>592
perl
0596nobodyさん2005/06/27(月) 02:14:33ID:???
大正解
0597nobodyさん2005/06/27(月) 02:18:26ID:???
ちょっとウケタw
0598nobodyさん2005/06/27(月) 02:28:57ID:???
>>590
ご返答有難うございます。
止まっていると思ったのは、
print SOCKET "User-Agent: " . $browser . "\n";
print SOCKET "Host: " . $host . "\n";
を外したら進んだためです。

具体的には、KeitaiPicutureという画像変換サービスで変換された
画像をSOCKETでとってくる仕組みを作っているのですが、
GET $directory$filename?User-Agent=UA
だと成功するんですよね。

とにかくご教示有難うございました。
0599nobodyさん2005/06/27(月) 03:10:20ID:???
>>598
そのサービスが$ENV{HTTP_USER_AGENT}じゃなくてクエリーのUser-Agentを見てるからだろ。
0600nobodyさん2005/06/27(月) 03:12:15ID:???
>>598
それから、telnetで直接やってみ。そこで止まってるわけじゃないから。
0601nobodyさん2005/06/27(月) 08:08:58ID:7ZY2M4BI
HERE。字あってるか忘れたけど、たぶんこれでできるはず。
0602nobodyさん2005/06/28(火) 16:25:00ID:l0OJ7VtD
#!/usr/local/bin/perl

use HTTP::Request;
use LWP::UserAgent;

my $url = 'http://www.yahoo.co.jp';
my $request = HTTP::Request->new(GET => $url);

my $ua = LWP::UserAgent->new;
my $response = $ua->request($request);

if($response->is_success) {
print $response->content;
} else {
print $response->status_line;
}

という LWP::UserAgent をテストするためのCGIを、サンプルを元に組んだのですが、
[Tue Jun 28 15:42:43 2005] [error] Premature end of script headers:
ということで 500 Internal Server Error になってしまいます。
Premeture〜ってぐぐってみたけどよくわかりません。
原因として何が考えられますか?
0603nobodyさん2005/06/28(火) 16:52:11ID:???
ようわからんが、print "Content-type: text/html\n\n"; が抜けてるとか。
06046022005/06/28(火) 17:06:17ID:???
>>603
ああああああああ〜〜
それでした〜〜
ありがとうございました〜〜
トホホ
0605nobodyさん2005/06/28(火) 17:37:14ID:???
>>604
あるあるww
0606nobodyさん2005/06/28(火) 17:58:49ID:???
すいません 質問があります。

--------------------------------
my %dir_name=();
readDir(\@dir_name);

sub readDir{
my $dirname_ref = shift;
$dirname_ref->{'aaa'}="BBB";
}
--------------------------------
を実行しても
Can't coerce array into hash at cron_day_table.cgi line 50.
とエラーになってしまいます。

何がいけないのでしょうか?
ご助力を頂けますと助かります。
0607nobodyさん2005/06/28(火) 18:11:08ID:???
>>606
エラーメッセージの通りじゃん。 readDir(\%dir_name); じゃないの。
06086062005/06/28(火) 18:17:44ID:???
あ、、、
本当だー
ありがとーございますっ

スレ汚し失礼いたしました。
06096062005/06/28(火) 19:37:41ID:???
たびたび本当にすいません 質問があります。

my %dir_name=();
my $dirname_ref = \%dir_name;

$dirname_ref->{'bbb'}='hoge';
$dirname_ref->{'ccc'}='hoge';
$dirname_ref->{'aaa'}='hoge';

my $key;
foreach $key(keys %dir_name){
print "$key -> $dir_name{$key}\n";
}
--------------------------------
として出力すると↓
--------------------------------
bbb -> hoge
aaa -> hoge
ccc -> hoge
--------------------------------
のようになってしまいます。

下記のように入れた順番通りに出力したいのですが
bbb -> hoge
ccc -> hoge
aaa -> hoge
そういった場合はどうすればよろしいのでしょうか?

ご助力を頂けますと助かります。
0610nobodyさん2005/06/28(火) 19:44:18ID:???
>>606
http://perldoc.jp/docs/perl/5.6.1/perlfunc.pod#item_keys_HASH
0611nobodyさん2005/06/28(火) 19:46:11ID:???
そういや、 pseudo hash ってなかったっけ?
もしかして、無かったことになった?
0612nobodyさん2005/06/28(火) 19:52:27ID:???
>>611
http://search.cpan.org/~nwclark/perl-5.8.7/pod/perl58delta.pod#Deprecations
0613nobodyさん2005/06/28(火) 19:59:09ID:???
>>612
なるほどねぇ
0614nobodyさん2005/06/28(火) 21:58:10ID:???
use strictしとけ。そういう単純ミスが防げるぞ。
0615nobodyさん2005/06/29(水) 20:47:26ID:???
>>609
スマートじゃないけど。

my %dir_name=();
my $dirname_ref = \%dir_name;

$dirname_ref->{'bbb'} = ['hoge', 1];
$dirname_ref->{'ccc'} = ['hoge', 2];
$dirname_ref->{'aaa'} = ['hoge', 3];

foreach my $dir (sort{$a->[1]->[1] <=> $b->[1]->[1]} map{ [$_, $dir_name{$_}] } keys %dir_name){
print "$dir->[0] -> $dir->[1]->[0]\n";
}
0616nobodyさん2005/06/29(水) 21:39:04ID:???
>>609
use Tie::IxHash
0617nobodyさん2005/06/29(水) 23:40:40ID:4HgpqCXd
変な質問ですみません。
どうしてこれで "0_" と表示できないのか教えて下さい。

$i = 0;
print "$i_\n";
0618nobodyさん2005/06/29(水) 23:46:24ID:???
>>617
偽として扱われてるから。
06196172005/06/30(木) 00:06:48ID:nq4lXHpH
すみません、自分なりに調べても分からなかったのですが、
ここでのアンダースコアはどのように効いているのでしょうか?
否定の演算子でもなさそうなのですが・・・
0620nobodyさん2005/06/30(木) 00:20:33ID:???
>>619
識別子には_も使えるから。($i_という変数も有り得る)
06216172005/06/30(木) 00:29:51ID:???
>>620
なるほど、よくわかりました。
どうもありがとうございます。
0622nobodyさん2005/06/30(木) 01:13:28ID:8FYD6O0q
掲示板みたいな簡単なCGIでも、フォームデコードとか細かくモジュール使うべきなんでしょうか?
簡単なの持っててもえーかな思ったんだけど、チェックボックスとかの複数選択がどーにもできんのです。。
複数のバリュあるときは配列にするのなら、
if (defined $form{$key}){
 if(ref $form{$key}){ push @$key,$value; }
 else{ @$key=($form{$key},$value); $form{$key}=\@$key; }
}
うろ覚えで書いたんで変かも・・・っていうか、@$keyがおかしいケド。こんな感じで良いのでしょうか?
プログラムそのものもperlが初めてなんで要領得なくて
サブルーチン内外で変数共有しない方がいいのかと思ったんだけど、リファレンスする配列が局所化できません。
0623nobodyさん2005/06/30(木) 01:17:33ID:???
#複数のバリューあるときは「リファレンス」?にするのなら
参考にしたスクリプトで使われてたcgi-liteだかではそうなってたような気が。
そして、sageってシステムがよくわからない・・・申し訳ないです。
0624nobodyさん2005/06/30(木) 02:47:40ID:???
ハッシュに配列つっこむならこんな感じ。
push @{$form{$key}},$value;

リファレンスするならこんな感じかの。
push @{$$form{$key}},$value;

でも、別に配列にこだわらなくてもいい気がする。
06256062005/06/30(木) 11:45:29ID:???
にゅおーー
本当にみなさんRESありがとうございます。

順番を保持する配列とその配列の要素をキーとするハッシュで
やる方法で自作し強引に解決(?)いたしました。

本当にRESどうもですっ
そのうちこちらで解決案を書ける人になれますようがんばりますですっ
0626nobodyさん2005/06/30(木) 12:21:53ID:???
>>621
後ろの文字を識別子の文字と区別したいときは { } を使う。

print "${i}_\n";
0627nobodyさん2005/06/30(木) 13:17:05ID:wTRNDiAZ
すいません、質問お願いします。

&decrypt(入力されたパスワード、登録されてるパスワード)
sub decrypt {
local($in, $dec) = @_;

local $salt = $dec =~ /^\$1\$(.*)\$/ && $1 || substr($dec, 0, 2);
if (crypt($in, $salt) eq $dec || crypt($in, '$1$' . $salt) eq $dec) {
return (1);
} else {
return (0);
}
}

パスワード認証のサンプルなんですけど、
入力されたパスワードが認証されれば1を間違っていれば0を返すサブルーチンなんですが、

local $salt = $dec =~ /^\$1\$(.*)\$/ && $1 || substr($dec, 0, 2);
if (crypt($in, $salt) eq $dec || crypt($in, '$1$' . $salt) eq $dec) {

↑の部分がどうしてもわからないのですが御教授お願いします。
0628nobodyさん2005/06/30(木) 13:22:47ID:???
多分、 Perl のコードがわからないというより crypt() がわからないんだと思う。
crypt() の仕組みが理解できてないとキツいと思うので、
「crypt パスワード」あたりでぐぐって調べてみるのが良いと思う。
0629nobodyさん2005/06/30(木) 14:05:04ID:wTRNDiAZ
>>628
ありがとうございます。crypt()は勘違いして覚えてました。
変換キーに2文字じゃなきゃいけないんですね。
それで

substr($dec, 0, 2);

の意味はわかったんですが

$dec =~ /^\$1\$(.*)\$/ && $1

と

crypt($in, '$1$' . $salt) eq $dec

の部分がまだわからないのですが
お願いします。

0630nobodyさん2005/06/30(木) 15:18:51ID:???
substr が分かるなら、こう書けば理解できる?
# - - - - - - - - - - - -
$salt = $dec =~ /^\$1\$(.*)\$/ && $1
 ||
if (
 length $dec >= 3 &&
 substr($dec, 0, 2) eq '$1$' &&
 substr($dec, -1, 1) eq '$'
) {
 $salt =
substr($dec, 2);
 chop $salt
;

}
# - - - - - - - - - - - -
if (crypt($in, '$1$' . $salt) eq $dec)
 ||
my $tmp = '$1$' . $salt;
if (crypt($in, $tmp) eq $dec)
# - - - - - - - - - - - -

とりあえず正規表現学んで来い、といいたい。
作者が $1$ *** $ とつけてるのはよくわからない。
0631nobodyさん2005/06/30(木) 15:19:50ID:???
ところどころ何故か無駄な改行が入ったw スマン
0632nobodyさん2005/06/30(木) 16:24:04ID:???
MD5とDESの違いだね。
0633nobodyさん2005/06/30(木) 16:30:42ID:wTRNDiAZ
>>630
ありがとうございます。
一行づつなら理解できるのですが、

$dec =~ /^\$1\$(.*)\$/

↑この表現は変数$decの頭が $1$ で任意の文字がいくつか入って
その後 $ の文字列にマッチするか否かと理解していいんでしょうか?
$1$ これって特別な意味あるんですか?

local $salt = $dec =~ /^\$1\$(.*)\$/ && $1 || substr($dec, 0, 2);

あと上の処理の順番がよくわらないんですが
A && B Aが真ならBを実行
A || B Aが偽ならBを実行
と言うのならわかるのですが
その辺もご教授願えないでしょうか
一応本を見ながらやっているのですがイマイチ理解できません。
0634nobodyさん2005/06/30(木) 16:41:02ID:???
ちゅーか、これで十分な気がするのだが。

sub decrypt {
crypt($_[0], $_[1]) eq $_[1];
}
0635nobodyさん2005/06/30(木) 16:59:34ID:???
質問です宜しくお願いします

$in{race}="aa";
$raceindex="bb";

if($in{race} == $raceindex){print "ok";}

exit;

これを実行すると$in{race}の内容と$raceindexの内容は同じではないはずなのに
if分は真となってokと表示されます
これはif分の書き方がおかしいのでしょうか
0636nobodyさん2005/06/30(木) 17:07:01ID:???
>>635
== は数値で評価する演算子。
この場合はどっちも 0 と評価されるので真になってしまう。
文字列を比較したい場合は eq 演算子を使う。

perlop - Perl operators and precedence (Perl の演算子と優先順位)
ttp://perldoc.jp/docs/perl/5.6.1/perlop.pod
0637nobodyさん2005/06/30(木) 17:13:09ID:???
>>636
有難う御座います
perlのスクリプト書くの1年ぶりですっかり忘れてました

無事解決しました
有難う御座いました
0638nobodyさん2005/06/30(木) 17:39:09ID:???
karame.comみたいな、特定のアドレスにメールが来たらその送信元アドレスに"Hello world!"とでも書いたメールを送信できるスクリプトを作りたいのですが、具体的にどうやればよいのかわかりません。
サーバからsendmailの使用は許可されているのですが、どうやったらメールが来たことが検出できるのかまるでわからないのです。
申し訳ありませんが一手ご教授下さいくださいですよ
0639nobodyさん2005/06/30(木) 17:42:21ID:???
>>633
$1$で始まるのはMD5でハッシュ化された文字列です
$1$から次の$までの文字列がハッシュ化のsaltになります
そのサブルーチンはDESとMD5の両方使えるようにしているようだけど意味無いと思われます
DES,MD5どっちを使うかはcrypt関数が知っておりsaltも自動的に判断されるので>>634で十分です。
0640わから〜ん2005/06/30(木) 19:18:36ID:UYjObKP/
1行目 my $edit_url = sprintf ("%s?choice=edit;id=%d", url (), $row->{id});
2行目 my $delete_url = sprintf ("%s?choice=delete;id=%d", url (), $row->{id});
3行目 print br (), br (),
4行目 "$row->{t} $row->{status}",
5行目 " [", a ({-href => $edit_url}, "Edit"), "]",
6行目 " [", a ({-href => $delete_url}, "Delete"), "]",
7行目 br (), "\n",
8行目 "$row->{content}\n";

1行目の sprinfで整形された文字列 my $edit_url変数に代入される。
2行目も同じ要領で、my $delet_url変数に代入される。
3行目は HTML表示

4行目 意味不明

5行目 1行目の変数が"edit"としてURL表示される。
6行目 2行目の変数が"delete"としてURL表示される。
7行目 HTML表示

8行目 意味不明

ご質問いたします。
(1)4行目の意味がわからない
(2)5行目と6行目がなぜ、editとdeleteのURL表示となるのか?
(3)8行目の意味がわからない

特に、(2)の質問を詳しく解説してください。(2)の用法について
ラクダ本に記述がありますか?

よろしくお願いいたします。
0641nobodyさん2005/06/30(木) 19:24:59ID:???
もう夏休みなのか?
0642nobodyさん2005/06/30(木) 19:27:29ID:???
>>640
ttp://perldoc.jp/docs/modules/CGI.pm-2.89/CGI.pod
0643nobodyさん2005/06/30(木) 19:59:14ID:???
「リファレンス」 を知らないのもあるような。 ぐぐれー。
0644わから〜ん2005/06/30(木) 20:11:02ID:UYjObKP/
PerlのCGIモジュールを使っているのですね。
必死にいろんな本読んでも、記述が無いわけですね。
URLのところを読んで、勉強します。

大変ありがとうございました。
0645>>6272005/07/01(金) 18:26:12ID:???
ありがとうございました。
$1$が謎だったので助かりました。
MD5とDESというのはレベルが高くてよくわかりませんが、
とりあえずそういうものだと思って頭の片隅においておきます。
今の段階では>>634のやり方で問題ないとわかっただけ十分です。
0646nobodyさん2005/07/01(金) 20:20:31ID:???
CGI.pmを使う利点は何ですか?
普通に$ENV{'QUERY_STRING'}などと変わらないような気がするのですが…
0647nobodyさん2005/07/01(金) 20:31:30ID:???
そう思うのなら使わなければいい
今時つかうやつも少ないだろうしな
0648nobodyさん2005/07/01(金) 20:55:17ID:???
あ、少ないんだ?
0649nobodyさん2005/07/02(土) 00:14:53ID:???
まじすか、今から使っていこうと思ってたのだがorz
0650nobodyさん2005/07/02(土) 01:12:37ID:???
フォームデコード程度なら必要ないっしょ
CGI::Liteだってあるし
0651nobodyさん2005/07/02(土) 07:05:02ID:???
CGI.pmの利点が分からないなら、使ってみればいいのに。
分からないかも知れないけど。
0652nobodyさん2005/07/02(土) 13:53:31ID:???
なんかPHPっぽいねw>CGI.pm
06536222005/07/02(土) 14:20:11ID:???
>>624
ありがとうございます。どうも、リファレンスで混乱してたようです^^;
「.=」して分割を考えるとかでも十分なのかな。。

モジュールは勉強したいとは思うけれど、種類の多さ機能の多さに・・・
そもそも、なんかもっと根本的な部分で知識と理解が足りてなさすぎる。。
0654nobodyさん2005/07/02(土) 23:30:34ID:???
>>653
そうそう、そんな感じ。
複数データはタブとか改行で区切るだけでも十分。
どうせ汚染チェックは必要なんだから、タブや改行はそこで取り除けばいいだけだし。

モジュールはセキュリティに気を配って書かれているのは良いけど無駄が多いからなぁ。
0655nobodyさん2005/07/03(日) 01:29:15ID:???
データの区切りと言えば、前、レコードの区切りは改行、フィールドの
区切りはタブでデータを記録してた時、フィールド内をさらに区切りたくて、
そのときタブも改行も使えないから何を使えばよいか迷って、結局^fだか^gを
使ったんだけど、こういうときにどういう制御文字を使う(または使う順序)の
約束事みたいなのあるかなと思って調べてわからなかったんだけど、
なにかあります?
0656nobodyさん2005/07/03(日) 01:33:17ID:???
データに含まれない文字
0657nobodyさん2005/07/03(日) 01:59:23ID:???
\x00-\x07\x0E-\x1A\x1C-\x1F\x7F\xFF あたりとか。
0658nobodyさん2005/07/03(日) 02:49:19ID:???
自分なりに調べてみても分からなかったので質問です。
ファイルオープンのとき、読み取りモードで開こうとしてファイルがなかった場合に、新しく生成させるために
&file_open(*FILEHANDLE,path)を定義してやってるんですが、

&file_open(FILE,$filepath);
flock(FILE,1);

とすると500Internal(以下略 が出てプロセスのタイムアウトとか言われます。
ファイルロックしているファイルにアクセスしようとしてるのかと思って調べてみましたがそうでもないみたいです。
なにか心当たりがあれば教えていただけませんか?
0659nobodyさん2005/07/03(日) 02:50:33ID:???
訂正
5行目 ×&file_open(FILE,$filepath);
      ○&file_open(*FILE,$filepath);
0660nobodyさん2005/07/03(日) 03:51:27ID:???
>>658
ここ参考
CGI設置について質問 【Part2】
http://pc8.2ch.net/test/read.cgi/php/1104624784/2
06616582005/07/03(日) 04:39:10ID:???
>>660
大変失礼しました。
もちろんローカルサーバでテストを行っていますが、「プロセス中にタイムアウトしました」としか
メッセージが出なかったもので、そのまま書いてしまいました。

3行ほどのテストプログラムを組んでコマンドプロンプトで実行させてみたところ、
いつまで待っても処理が終わらず、さらに問題と思われる行の前後で文字列を出力させてみたところ、
前ではうまく出力しますが後では出力しないため、問題がこの行にあるのは明白だと思われます。
&file_openのソースは以下のとおりです。

sub file_open{
local *FILE = shift;
my $filename = shift;
if(! -e $filename){
my $fntemp = $filename;
$fntemp =~ s/^(\>|\<|\+)*//;
open(NEW,">$fntemp");
close(NEW);
}
if(!open(FILE,"$filename")){&sub_error(2);}
return;
}
0662nobodyさん2005/07/03(日) 07:52:34ID:???
>>658-661
http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlfaq5.html#How_can_I_make_a_filehandle_loca
http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlfaq5.html#How_can_I_use_a_filehandle_indir
06636582005/07/03(日) 14:25:42ID:???
>>662
読ませて頂きましたが、使い方は私ので合っていると思います。
ただ、ファイルオープン後にflock関数が使えないという点について何か教えていただけませんでしょうか。
0664nobodyさん2005/07/03(日) 14:52:54ID:???
>>663
>>662を読めバカ
0665nobodyさん2005/07/03(日) 15:55:28ID:???
わざわざへんてこなサブルーチン作ってバグ呼び込むようなことしなくても
sysopenでO_CREAT使えば一発なわけだが。
06666582005/07/03(日) 16:00:37ID:???
ぜんぜんわかんないです・・・。。。
ファイルハンドルを局所化して使うと、サブルーチンの外ではflockは使えないのですか?
0667nobodyさん2005/07/03(日) 16:26:41ID:???
>>666
試してみたがお前のプログラムは限定された状況でなら動くので、
問題は別のところにあると思われる。
% cat foo.pl
my $filepath = "foo";
&file_open(FILE,$filepath);
flock(FILE,1) or die "flock: $!";
sub file_open{
local *FILE = shift;
my $filename = shift;
if(! -e $filename){
my $fntemp = $filename;
$fntemp =~ s/^(\>|\<|\+)*//;
open(NEW,">$fntemp") or die "open NEW: $!";
close(NEW);
}
if(!open(FILE,"$filename")){&sub_error(2);}
return;
}
(続く)
0668nobodyさん2005/07/03(日) 16:26:56ID:???
(続き)
% strace perl foo.pl
(中略)
stat64("foo", 0x814d0c8) = -1 ENOENT (No such file or directory)
open("foo", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbffff5a8) = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(3, 0, [0], SEEK_CUR) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
fcntl64(3, F_SETFD, FD_CLOEXEC) = 0
close(3) = 0
open("foo", O_RDONLY|O_LARGEFILE) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbffff5a8) = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(3, 0, [0], SEEK_CUR) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
fcntl64(3, F_SETFD, FD_CLOEXEC) = 0
flock(3, LOCK_SH) = 0
close(3) = 0
exit_group(0) = ?

ファイルは開かれているしflockも正常終了している。
0669nobodyさん2005/07/03(日) 16:39:25ID:???
ただし以下のような問題があるのできちんと勉強して書き直した方がいい。

file_openに渡している'FILE'はただの文字列なので、呼び元と
file_openが別パッケージのときにおかしくなるだろう。

open(NEW,..)の戻り値を見ていない。せめてdieぐらいしとけ。

-eで調べてなければファイルを作っているが、ここがアトミック
に実行されていないのでそのうちメチャクチャになるだろう。

最後の問題のおかしくなるシナリオの例はこんな感じだ。
(プロセスA) -eでファイル調べたらなかった
(プロセスB) -eでファイル調べたらなかった
(プロセスA) ファイル作ってflockしていろいろ書き込む
(プロセスB) open(NEW ">$fntemp")いきなりやるのでAが書き込んだファイルが空っぽに
0670nobodyさん2005/07/03(日) 16:41:33ID:???
>>667-669
>>659
06716582005/07/03(日) 17:01:45ID:???
>>667-669
ありがとうございます!
視点を変えてもうすこしバグフィックスしてみますね。
最後の問題は、もう少し煮詰める必要がありそうですね。
open(NEW,"+>$fntemp");truncate・・・のほうがいいんでしょうか。

ともあれ、本件は本当にありでした。
まだ問題の解決になっていませんが、とりあえず問題がこのルーチン以外にあるということが分かったのでもう少し考えて見ます。
0672nobodyさん2005/07/04(月) 01:53:07ID:???
>>655
データファイルとして保存する際、特殊な制御文字を使うのはあまりおすすめしない。
テキストエディタでメンテナンスする時のことを考えるとね。

スペースとかカンマとかで区切っちゃっていいんじゃないの?
checkboxやselectでスペースやカンマを使用しなければ済む話なんだから。
0673nobodyさん2005/07/04(月) 10:25:04ID:???
他のシステムで読み書きする必要がなければ
Storableが楽だと思う。
0674nobodyさん2005/07/04(月) 10:44:04ID:???
>>673
Data::Dumper の Dump()なら単なるテキストファイル
0675nobodyさん2005/07/04(月) 22:46:13ID:???
script内に、ある package が取り込まれている、ってことをどう調べたらいいのかな?

# Hoge->new() があるかどうか、ってことは ↓ みたいにすればできるみたいなんだけど

use strict;
print defined Hoge; # これは error
print defined &Hoge::new ? 1 : 0; # 1
print defined Moge; # これも error
print defined &Moge::new ? 1 : 0; # 0

package Hoge;
sub new {}
0676nobodyさん2005/07/04(月) 23:59:48ID:???
>>675
print exists $main::{"Hoge::"};
0677nobodyさん2005/07/05(火) 00:25:37ID:???
うわ、できてる! すごっ
>>676 ありがとうー。

でも何で? どういう理屈?
リソースとかあったら教えてほしいわ。
0678nobodyさん2005/07/05(火) 01:00:15ID:???
>>677
http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlmod.html
0679nobodyさん2005/07/05(火) 01:31:57ID:???
・・・あ、あった(笑)
ありーー
0680nobodyさん2005/07/05(火) 04:53:09ID:???
@arr = ([0, 1, 2], [3, 4, 5]); の状態で
@{ $arr[0] } とすると
$arr[0]にある無名配列の参照をデリファレンスしてリストとして見ている
という意味でしょうか?
0681nobodyさん2005/07/05(火) 05:01:50ID:???
頼むから訊く前に試してくれ
06826802005/07/05(火) 05:46:53ID:???
試した後でした。失礼しました。
■ このスレッドは過去ログ倉庫に格納されています