Perl コーディング初心者質問コーナー Part36
■ このスレッドは過去ログ倉庫に格納されています
0001nobodyさん
04/07/14 13:23ID:???【投稿する際の注意】
質問するときは内容をよく吟味してから投稿してください。
「コマンドの意味がわかんない」とかはマニュアル見ましょう。
回答者さんは何でも屋じゃありません。
1: 自分はこう言う事がしたい。
2: それでこんな風にやってみたが・・・
3: こんなエラーが出て上手く行かなかった。
最低でも1と3が無いと誰も答えられないよ。
ソース貼る時は、全角スペースでインデント忘れずに。
良い回答は良い質問から。一緒に勉強しましょう。
過去ログやお勧めサイトは >>2-10
0511nobodyさん
04/08/10 22:40ID:???print <<EOF;
here-document.
EOF
この三行で普通に動くが?
ヒアドキュメントの終端は「終端文字列だけから成る*行*」でなければ
ならないので、終端文字列の後ろに改行は必要だが、それ以下には
何ら必要でない。
>>510
訂正ありがとう。
0514nobodyさん
04/08/11 04:28ID:???$a{aa} = 1;
------------------
my $a;
$a{aa} = 1;
------------------
my $a;
$a->{aa} = 1;
の違いがイマイチ分かりません。
解説してる所とか無いですか?
0516nobodyさん
04/08/11 04:37ID:???二番目はありえない気ガス
0518nobodyさん
04/08/11 08:46ID:???真ん中はスカラー変数$aをmyにしてるが、2行めは%aへの操作で
別にエラーになるような間違いじゃないがその2行はなんの関連
もない。
下はスカラー変数$aがmyになっていて、最初はundefが入っているが、
$a->{aa}=1;したときに自動的に無名ハッシュが生成されてその
リファレンスが$aに入る。で、その無名ハッシュのキーaaに対応
する値が1になる。
0519509
04/08/11 09:33ID:???>>510-511
>終端識別子の「HTML_DOCUMENT」のケツに、改行が入ってねぇんじゃねぇの?
だから
>ファイルの最後の行数=終端識別子のある行数ではエラーになる
と同じ意味だろ。改行いれずにどうやって
ファイルの最後の行数!=終端識別子のある行数
にするの?
>>513
行数がわからないと、文法チェックもできないからちゃんと勉強しれ。
0520nobodyさん
04/08/11 09:52ID:???>>506 での "空白行" が >>508 では "空白文字" と捉えられてる。
空行とか改行文字って表現にしたほうが良かったんじゃない? > 語弊の原因
# 空白行ってあまり聴かないし
0521黒死犬 ◆EgxBlf8nvc
04/08/11 11:59ID:???>>519
うちの環境だと、それでもエラーになりませんが・・・
でも前のバージョンでエラーになった覚えがあるので、ひょっとしたら改善されたのかもしれません
0522nobodyさん
04/08/11 12:30ID:???確かにふつーは空行だな。
でも空行ってのは行頭に\nがあるわけで、この場合必要ない。
必要なのは終端識別子の末尾の改行。
そこでファイルエンドなら問題ない。
>>519
>>ファイルの最後の行数=終端識別子のある行数ではエラーになる
>と同じ意味だろ。
とか言われても、お前にしか通じん言葉では同意は得られんと思うが?
行数じゃなくて行番号ならまだしも。
ただ、
HTML_DOCUMENT[\n]
[EOF]
となっている場合、終端識別子の行がファイルの最終行なわけだが、
これなら改行が入っているから問題ない。
一部のエディタじゃ[EOF]にも行番号が表示されるから、そこが最終行だと
勘違いしてんじゃねえのか?
0524nobodyさん
04/08/11 13:02ID:???$value =~ s/1/1/g;
みたいなのを1〜9まで繰り返すしか思いつかないのですが、一発でやるようなコーディングはありませんか?
0525nobodyさん
04/08/11 13:41ID:???0528nobodyさん
04/08/11 15:05ID:???$ref_exchange = ['0','1','2','3','4','5','6','7','8','9'];
$value =~ s/$ref_exchange->[$_]/$_/g for 0..9;
printf "%s\n", $value;
かなりお間抜けかも、、、
0529nobodyさん
04/08/11 15:17ID:???プラス、マイナスとかのこと?
print pack "c*" 0xa4,0xa2;
print pack "C*" 0xa4,0xa2;
EUCだと両方「あ」って表示されて差がわかりません。おながいします。
0530nobodyさん
04/08/11 15:42ID:???use Jcode;
$value = '1234567890';
$value = Jcode->new($value)->tr('0-9', '0-9')->euc;
print $value, "\n";
または
use utf8;
use encoding 'euc-jp', Filter=>1;
$value = '1234567890';
$value =~ tr/0-9/0-9/;
print $value, "\n";
0531nobodyさん
04/08/11 15:47ID:???packするときは違いがでない。unpackすると違いが出る。
print unpack "c*", "\xff";
print unpack "C*", "\xff";
0533529
04/08/11 16:09ID:???print unpack "c*", "\xaf";
print unpack "C*", "\xaf";
だと
-81
175
で
print unpack "c*", "\x7f";
print unpack "C*", "\x7f";
だと
127
127
で同じ。一体どういう仕組みですか?
0534529
04/08/11 16:13ID:???print unpack "C*", "0xff";
print qq\<br>\;
print unpack "C*", 0xff;
print qq\<br>\;
print unpack "C*", "\xff";
print qq\<br>\;
print unpack "C*", \xff;
は
48120102102
505353
255
83676576658240481204957555350489941
になるんですが、どうしてクォートありなし、\xと0xで違うものになるんでしょうか?
\xは0xと同じ意味だと思ってたのですが。
0535nobodyさん
04/08/11 16:15ID:???Perlじゃないけどこんなページ見つけた
ttp://www.kab-studio.biz/Programing/PragmaTwice/Main/056.html
0536524
04/08/11 16:16ID:???Jcodeは使ったことないので多分自宅のテスト環境用のactiveperl5.6.613には入ってないと思いますが
ppmを使ってインストールができるモジュールなのでしょうか?鯖(joe's)でも使えるか確認してみます。
0538529
04/08/11 16:58ID:???符号あり-128〜127
符号なしは0〜255
16進数二桁だとこんなかんじなんですね^^mysqlのtinyintと同じ感じ。
わかりやすいサイトでした。534については載ってませんでした。
0539nobodyさん
04/08/11 17:31ID:???perlのリテラルについてよく勉強しろ。
"0xff"
'0', 'x', 'f', 'f'の4文字からなる文字列
48120102102
'0'の文字コード48, 'x'の文字コード120,
'f'の文字コード102, 'f'の文字コード102
がくっついて出力された
0xff
16進数のff=10進数の255
505353
255がまず文字列に変換され、各桁の文字コード
'2'が50と'5'が53がくっついて出力された
"\xff"はいいだろう。
\xff
裸の文字列リテラルxffの前に\演算子がついて
それのリファレンスをとったことになる。
83676576658240481204957555350489941
スカラーのリファレンスは文字列に変換すると
SCALAR(0xほげほげ)と変換される。(0xほげほげ
はポインタかなんかを16進表示したもの)
'S'は83,'C'は67,...(以下略)
0540nobodyさん
04/08/11 17:36ID:???RGBフォーマット(ベタイメージ)の画像があるのですが、
(サイズや色数情報などば別の変数に持っています)
これをPNGとして書き出すのにいい方法はありませんか。
テンポラリファイル等はできるだけ作りたくないのですが。
とりあえず新しくImage::Magickオブジェクトを作ったあと、
SizeとDepthをセットしunpackでforで1ピクセルずつ16進表記に直してSetした後、
Writeする方法でやってみたのですが、
1ピクセルずつSetを行うととんでもなく遅いので…
0541nobodyさん
04/08/11 17:37ID:???○forで1ピクセルずつunpackで16進表記に直してから
0543529
04/08/11 18:31ID:???非常にわかりやすい説明ありがとうございます。
ところで"\xff"はどういう感じなのでしょうか?
print "\xff"とするとEUCでは「・」だけ表示されます。
0xff → 先に255に変換されてから関数に渡される。
"\xff" → 255に変換せずに16進数のffという値を関数に渡している。
であってますよね?
0544nobodyさん
04/08/11 18:49ID:???"\xff"は16進数のff(=10進の255)1バイトからなる
文字列。
これはEUCとしては使ってない部分なので、なにか
表示されるとしても苦し紛れになんか出してるだけ
だと思うよ。
0545nobodyさん
04/08/11 18:53ID:???foreach my $foo (@array){
$foo=~s/aaa/bbb/;
}
とすると@arrayに書き戻せないですよね?
for (my $i=0; $i >= @#array; ++$i){
$array[i]=~s/aaa/bbb/
}
これでいけると思うんですけど、ほかにシンプルな方法はありますか?
0547nobodyさん
04/08/11 19:45ID:???0548nobodyさん
04/08/11 19:47ID:???思い込みで試してなかったんですが
やってみたらうまくいきました
ポケットリファレンスを見て書き戻せないのかなぁと勘違いしてて
今オライリーで見直したらこの書き方でいけるってのがわかりました
0549529
04/08/11 19:48ID:???ありがとうございます。いろんなサイトのpack,unpackの解説をみてますがやっと少しだけ理解できました。
print unpack"C*","\x41";
これは10進の65に当てられている文字列Aを10進の65に変換して返してるんですね。なので
print unpack"C*","A";
と同じ。でその逆がprint pack "C*",65;ってわけですね。
でもchar値int値long値short値というのは具体的にどういうものかがわかりません。
char値とは16進2桁、2進で言うと8桁=8ビット???自分で言っててよくわかりませんorz
pack TEMPLATE,LIST;
LISTをTEMPLATEのフォーマットでパックするみたいに解説されてますが、例えばH型(16進文字列)なら
"\x41" eq pack "H",41 で、内部的な流れも理解できる気がします。
C型はLISTを10進数での文字列で捉える?それを16進文字列に変換して返すみたいな・・・
なんか違いますよね。char値があってそれを利用してpackで10進数から16進数文字列に変換できるだけで
元々char値をそんなためにあるわけでもないですよね?
ぐぐてもchar値とはみたいなサイトが見つからないんですよねorz
0550nobodyさん
04/08/11 19:57ID:???おおこれは便利
0551529
04/08/11 19:57ID:???char値 符号付
10進で言えば -128〜127
int値 符号付
10進で言えば -2147483648〜2147483647
short値 符号付
10進で言えば 不明
long値 符号付
10進で言えば 不明
結局扱える大きさが違うだけですか?でもそうなるとpackの型のC等の意味と内部的な処理内容がよくわかんないんですよね。
だんだんスレ違いになってきたので、後は自分で色々なサイトを読んでみます。
親切に対応してくださってありがとうございました。失礼します。
0552nobodyさん
04/08/11 20:04ID:???blobToimageでやってみました。
なぜかRGBでblobToimageやるとうまくいかないので、
PPMでやってヘッダだけ付け足したらできました。
まともな速さになりました。ありがとうございました。
0553nobodyさん
04/08/11 20:09ID:???これって漏れも初めて知ったんだけど怖くない?
map s/kuroguro/hage/,@family;
妄想の中で家族が全員はげたところを創造してみたら、現実にみんなはげちゃったーーーーー
って冗談じゃなく怖いな。
0554nobodyさん
04/08/11 21:10ID:???%83%7E%83P%83l%83R
みたいになってますが、これは何エンコードなのでしょうか?
同じ形式でエンコードしたいのですが
$str =~ s/(\W)/'%' . unpack('H2', $1)/eg;
$str =~ tr/ /+/;
では同じ形式にはならないです。(URIエンコードで調べて見つけたサイトに乗ってたコードです)
ちなみに
$value = '%83%7E%83P%83l%83R';
$value =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C",hex($1))/eg;
print $value;
>ミケネコ
です。
0555nobodyさん
04/08/11 21:16ID:???<q cite="http://www.kt.rim.or.jp/%7Ekbk/perl5.005/perlstyle.html">
戻り値をただ単に捨ててしまうような void 文脈で、grep()やmap()、
`backticks` (訳注: `ls`のようにバッククォートで括った実行文の
こと)を使うことは避けましょう。そういった関数はすべて戻り値を
持っているのですから、それを使うべきです。戻り値に用がない
のであれば、代わりにforeach()を使ったループか system()関数
を使いましょう。
</q>
s/aaa/bbb/ for @foo;
>>554
http://www.din.or.jp/~ohzaki/perl.htm#JP_Escape
0556nobodyさん
04/08/11 21:16ID:???は戻値のためにバッファ用意されんのが無駄。
戻値いらんのなら、
s/aaa/bbb/ for @foo;
でええやろ。
0557556
04/08/11 21:17ID:???0559554
04/08/12 00:07ID:???そのサイトを見て自分でやってみましたが、
$str = "ミケネコ";
$str =~ s/(\W)/'%' . unpack('H2', $1)/eg;
$str =~ tr/ /+/;
では
%83%7E%83P%83l%83R
になりませんがどうすればよいですか?
0561nobodyさん
04/08/12 00:19ID:???0562nobodyさん
04/08/12 00:22ID:???ではヤダ、って話じゃないのかしら?
0565nobodyさん
04/08/12 01:02ID:???になってしまう。という話かもしれん。
0566nobodyさん
04/08/12 01:59ID:???map s/aaa/bbb/, @foo;
は生理的に気持ち悪いんだよ。
そんなこと気にも止めんorそこまで手の回らん奴には
分からん感覚さね。
速度が欲しけりゃCで書け。
0567nobodyさん
04/08/12 02:03ID:???お前が生理的に気持ち悪いだけだろ?
オレはそれは一種のイディオムだと思ってるので
別に読みにくいとは思わんし気持ち悪くもないよ。
0568nobodyさん
04/08/12 02:10ID:???可読性まで考えてっておかしくないか?
map { ブロック } リスト は普通の書き方だろ。
単にmapを使い慣れていないから見慣れないものを
気持ち悪いことにしてるとしか思えない。
0569nobodyさん
04/08/12 02:25ID:???つーのもあるわな。(非効率)
0571nobodyさん
04/08/12 02:43ID:???0572nobodyさん
04/08/12 02:47ID:???今回の問題でmapを使うのは変わった書き方と言われてるぞ(ゲラ
0575566
04/08/12 04:08ID:???書き方の問題じゃねえっての。理由は555に書いてあんだろ。
mapにはmapの使いどころってもんがあんの。
何でもmap使えばいいってもんじゃねえのよ。
仕事で人のコード読んだりコードレビューだのが増えてくると
自然と身につくんだよ。そういう感覚が。
0576nobodyさん
04/08/12 07:52ID:???0577554
04/08/12 10:02ID:???これはshift_jisだったんですね;すみませんでした。
ところでShift_JISの「ケ」は83Pになるみたいですが、これはどういうことでしょうか?
文字コード表を見てみたら、0x83,0x4Fの「グ」の一つ右側にあるので
0x83,0x4F+1で0x50?になるのかと思ってたんですが、0x83Pなんですね。
$str =~ s/([0-9a-fA-F][0-9a-fA-F])/pack("C",hex $1)/eg;
これでデコードするときにPは置換されませんよね?0x83で返してくる値にPを付けると
shift_jisではケになるんですか?ケの2バイト目は他とは違う扱い方がされてるんでしょうか?
0578554
04/08/12 10:04ID:???パーセントが抜けててごめんなさい。
0579nobodyさん
04/08/12 10:05ID:???つーかアスキーコード表読めよ
0581nobodyさん
04/08/12 10:07ID:???0582nobodyさん
04/08/12 10:15ID:???Perlは大規模開発に向かないって誰が言ったんだろうね?
Perlの言語仕様なら何の問題も無いと思うんだけど。
0583nobodyさん
04/08/12 10:25ID:???0584nobodyさん
04/08/12 10:35ID:???0585nobodyさん
04/08/12 10:37ID:???0587nobodyさん
04/08/12 10:40ID:???カプセル化という名の強制隠蔽は、技術者のレベルと意識の低さを
言語仕様で補おうというもの。
決められたルールに厳重に従ってコーディングされるならば、
カプセル化は必要ない。
0588nobodyさん
04/08/12 10:49ID:???だから仕事でもPerlを使ってる。
さっさと作って儲けるのが第一なんで。
0589nobodyさん
04/08/12 10:51ID:???0590nobodyさん
04/08/12 11:05ID:???必死だなw
藻前らもうPerlのスレには来んでええぞ
0592554
04/08/12 11:38ID:???ありがとうございます。しかしそれだと何故に
%83%7E%83P%83l%83R
が
%83%7E%83%P%83%l%83%R
にならないんでしょうか?「ミ」の文字はちゃんとバイトの前に%が付いているのに。
0593nobodyさん
04/08/12 12:10ID:???URLエンコーディングについて理解して下さい。
自分で何も出来ないんですか?
http://www.mars.dti.ne.jp/~torao/rfc/rfc1738-ja.txt
0594554
04/08/12 13:43ID:???ありがとうございます。読んでみましたが、
>付加的に、8ビット文字は文字 "%" に続く 8ビット文字の 16進数値となる 2
>つの 16進数 ("0123456789ABCDEF") の 3文字により符号化される。(文字
>"abcdef" も 16進数符号化で使われるだろう。)
やはり%が付くと思うんですが、どうして%83%Pにでなく%83Pなのか理解できません
もしかして、元々shift_jisの「ケ」は"\x83","\x50"ですが、エンコード処理中に
先に"\x83"だけ置換されて、次は"\x50"になる。そしてその時に"\x50"=Pなので
/(\W)/単語構成文字以外に一致
Pは単語構成文字なので一致せずに処理が行われない。だから%もつかない。
そしてデコードでも処理はされないけど
"\x80","\x50"をshift_jisで読むと「ケ」と解釈する。
!?これで正解ですよね?
0595nobodyさん
04/08/12 14:43ID:???8ビット文字は、もしそれらが US-ASCII コード文字セット内の印字可能な文
字でない場合、その文字の使用が安全でない場合、もしくはそれが特殊な URL
スキーム内で何か別の処理のために予約されている場合に符号化されなければ
ならない。
印字可能な文字でないとは:
URL は US-ASCII コード文字セットの印字可能な文字でのみ記述される。8
ビット文字の 80-FF は US-ASCII で使われていない。そして 8ビット文字
00-1F と 7F は制御文字に相当する。これらは符号化されなければならない。
さっきの所のコピペ
0597nobodyさん
04/08/12 16:05ID:???$dbh = DBI->connect ($dsn,$user,$password,{ AutoCommit => 0 , RaiseError => 1 });
$sth = $dbh->prepare(
qq|select * from test|
);
$sth->execute;
@a = $sth->fetchrow_array;
jcode::convert(\$_ , "euc" ) foreach @a;
print $_,"<br>" foreach @a;
$dbh->disconnect;
みたいにしてtestテーブルから全レコードを引き出そうと思ったんだけど、何故か1行しか取り出せない。
一気に全レコード取り出すにはどうやればいいの?
0598nobodyさん
04/08/12 16:12ID:???0599nobodyさん
04/08/12 16:26ID:???fetchrow_array は、
DBの1レコードを1つの array にして取り出すメソッドで、
array の各要素には1レコード中の各フィールドが入る
全レコードを取り出すときには >>598 のようにやるか
あるいは while で回すか
0600597
04/08/12 17:02ID:???selectall_arrayrefがレコード全部をスカラで返してくるのかな?
でもこれSQL文を引数にしるんだな。なんかprepareしたいけど。
>>599
そういうことね。わかりやすい説明thx
ところでprepareって元々何のためあるの?XSS対策にサニタイジングしてくれるわけではないでしょ?
なんかprepareしておいたほうが安全だよって話をよく聞くんだけど。
0602597
04/08/12 17:29ID:???ありがととりあえず
$a = $sth->fetchall_arrayref;
から試したけど、この子はリファレンスの中にリファレンスでさらにリファレンス(これがfeachrow_arrayかな)が入ってるのね。
MySQLの中身がShift_JISで、perlはeucで出力はShift_JISだからちょっと面倒;
とにかくthx!
0603nobodyさん
04/08/12 17:36ID:???暇だからコーディングしちゃった^^
for ( $i=0 ; $i<$#{$a} ; $i++ ){
jcode::convert( \$_ , "euc" ) foreach @{$a->[$i]};
}
0604nobodyさん
04/08/12 17:39ID:???か
$i<@$a
じゃない?
0605nobodyさん
04/08/12 17:40ID:???shell>perl -e "@array=qw/1 2 3 4 5/;
while(@array){print}"
とかしたことある?
0607nobodyさん
04/08/12 17:46ID:???この場合インデックスはいらないと思うので、
foreach (@$a) {
foreach (@$_) {
Jcode::convert(\$_, 'euc');
}
}
でいいんでねーの?
0608597
04/08/12 17:56ID:???せっかくだから遣わしてもらおうと思ったら
for ( $i=0 ; $i<=@{$a} ; $i++ ){
jcode::convert( \$_ , "euc" ) foreach @{$a->[$i]};
}
多分こう書いた。
ループから抜けられず延々HDDがガリガリ(表現悪いけど、処理してる音);
なんとか再起動できたけど、よくエラーにならなかったなとceleron2.7GHz/xp
のすごさを確認したよw
ていうかなんでループから抜けられなかったんだ?もしかしたら
$i=@{$a}
って書いちゃったのかも;
0610597
04/08/12 18:04ID:???それの方が安全そうwと思って試したけどできんかったよ?
それの後に
print $a;
で何も表示されず(リファレンスが表示されると思ったけど)
print @{$a};
でも何も表示なし・・・(リファレンスの配列が・・・)
print @[$a->[0]};
やっぱりだめで何も表示されず・・・・(実際のレコードの中身が・・・・)
603のやつではちゃんと表示されるけど、デリファレンスの方法が違うん?
■ このスレッドは過去ログ倉庫に格納されています