Perlについての質問箱 64箱目
■ このスレッドは過去ログ倉庫に格納されています
CGIについての質問は板違いです。WEBプログラミング板でどうぞ。 CGIとPerlの区別がつかない人もWEBプログラミング板に行ってください。 (WEBプログラミング板: https://medaka.5ch.net/php/ ) このスレでは(CGI以外の)純粋にPerlのみに関係する質問を取り扱っていこうと思います。 スレ違いの質問にはスルーか、速やかな誘導をお願いします。 荒らしはスルー推奨。 "The duct tape of the Internet" こと、Perlについての質問箱です。 "There's more than one way to do it" ということで、 Perlの奥深さについて皆で語り合い、追求してまいりましょう。 www.perl.org/get.html Download Latest Stable Source (5.28.1) ▼前スレ Perlについての質問箱 61箱目 http://toro.5ch.net/test/read.cgi/tech/1381561905/ Perlについての質問箱 62箱目 http://toro.5ch.net/test/read.cgi/tech/1385039352/ Perlについての質問箱 63箱目 https://mevius.5ch.net/test/read.cgi/tech/1392820583/ ググれば普通に見つかる Windows Subsystem for Linux でダブルクリックで sh ファイルを実行する https://dskjal.com/PC/run-sh-on-bash-on-ubuntu-on-windows.html Windows 10のbashのコマンドをGUIから起動させるには? http://kako.com/blog/?p=16372 WSL2は、Windows側のファイル属性とかちゃんとふつうにあつかえるようになったんか? WSL1のときは完全別物で、全然ダメやったが。 WSL1もWSL2も同じ。Linuxのファイル属性として正しく扱えるようになった。 Windowsのファイル属性をLinuxアプリが正しく扱えることはありえないから 逆の発想でLinuxとして正しく扱える方向に舵をとった。 Linuxアプリから正しく扱えないなら意味ないでしょ? そもそもファイル属性はWindowsの方が高機能で Linuxは、いろいろ拡張入れたら別だが 基本のファイル属性はUNIX初期の頃から変わって無くてかなり貧弱。 Windowsの高機能なファイル属性をそのLinuxにマッピングすることは出来ない。 逆にLinuxのファイル属性を全てWindows側に持たせることは可能 こうすることで全てのWindowsのファイルをLinuxで正しく扱えるようになった。 漏れは、Ruby のバージョンマネージャー、rbenv をWSL, Ubuntu 18.04 に入れた。 これで、Linux 側に、好きなバージョンのRubyを入れられる Windows 10 側には、VSCode を入れて、拡張機能のRemote WSL を入れる これが基本! DBIの動作についてお聞きしたいことがあります。 my $dbh = DBI->connect(接続情報); my $sql = 'パラメータ付きクエリ'; my $ret1 = $dbh->selectrow_arrayref($sql, undef, 'A'); my $ret2 = $dbh->selectrow_arrayref($sql, undef, 'B'); my $sth = $dbh->prepare($sql); my $ret3 = $dbh->selectrow_arrayref($sth, undef, 'A'); my $ret4 = $dbh->selectrow_arrayref($sth, undef, 'B'); このようなコードで$ret1と$ret2には'A', 'B'それぞれのパラメータを使用した結果が入るのですが、$ret3は$ret4と同じ'B'を使用した結果になってしまいます。 selectrow_arrayrefに同じステートメントハンドラを渡して複数回実行すると、リファレンス実体が最後に実行した結果で上書きされてしまうような雰囲気でした。 Perl 5.10.1 & DBI 1.609の環境と、Perl 5.16.3 & DBI 1.642の環境で試してどちらも同じ結果になったのですが、こういうものなのでしょうか…。 >>305 アホか? バッチファイルでwsl起動してその中で実行してるだけじゃん レジストリ編集の方もパワーシェルに引数渡してwsl起動してるだけだ これじゃあcygwin使ってやるのとなんら変わっとらん >>312 あのさ、おまえ頭悪いよ? 目的を一番ラクに実現する方法が 目の前にあるというのにそれを使わないのはアホだろ ネイティブのPerlを使えばいい 今更PerlのWindows移植版なんかいらんよ。 Windows移植版なんてcygwinと何も変わらん >>311 試してみたけど確かに同じ配列が変えるね オライリーのDBI本見たらそう書いてあった selectrow_arrayって方を使ってリストコンテキストで受けるといいみたい >>314 やはりそうですか… selectrow_hashrefを使うと$sqlでも$sthでも'A', 'B'それぞれの結果が返るので、selectrow_arrayrefだけ期待と違う動作をしている気がします。(バグ?) >>315 バグというか仕様だと思う 作者の書いたオライリー本にも書いてあったから意図的なはず 今更変更できないからこのままになってるんだろうね >>316 なるほど。 それでは今後、selectrow_arrayrefは注意して使うようにしたいと思います。 ありがとうございました。 >>313 へー バッチファイル作ったりトリッキーな関連付けまでしないと動かないのが一番楽な方法ねー cygwinで全く同じことができるしwin移植版perlならそのまま実行できちゃうんだけどね ところでエクスプローラからどうやったらwsl内のファイルが見えるんだい? >>311 selectrow_arrayref は最初の1行しか返さないからということはない? ぐえ。リロード忘れたらとっくに話が終わっていて間に沢山の書き込みが BOOKOFFに100円で売っていたPerl/CGI辞典によると、 selectrow_array:先頭行 selectcol_arrayref:最初のフィールド selectall_arrayref:すべて >>318 Windows版Perl使って Windowsで動かないーってやるより、 安心して使えるバッチファイルを使ったほうがシンプル いやいやw WSLならバッチファイルなんか使わなくてもエクスプローラーからダブルクリックでWSL上のスクリプトを直接実行できるんでしょ? やり方教えてよ windows版perlならバッチファイルなんか使わなくてももちろん出来るからねw それとwindows版perlだと何が動かないのかな〜? バッチファイルとかっていったい何歳の爺さんなんだよ >>323 普通に、wsl.exe+スクリプトファイルのショートカットを作るだけ >>325 やってることはバッチファイルと同じじゃん Ruby でも、MSYS2/MINGW は、日本語でバグル・日本語入力できない。 一方、WSL は、日本語でバグらない! WSL が出たから、次第に、Windows 版のRuby Installer は、使われなくなっていく それに、VSCode の拡張機能、Remote WSL が出たから、 Windows 10 では、Ubuntu 18.04 が標準になる プロジェクトも、Windows 側のC: ドライブじゃなくても、 Linux 側に置いて、Remote WSL でアクセスできるので、本番環境に近い Windows/Linux のファイルのアクセス権限の違いに、困らない! >>326 それで実現できるだろ しかも完全にちゃんと動くPerlで ハア? WSLはwindows版perlより楽できるんじゃないの? なんでわざわざそんな面倒なことすんの? それとエクスプローラからWSLのファイルが見えてそれをダブルクリックで実行できるって話はどうなったの? WSLはあくまでLinux的システムなアプリであって、Windows側とはやっぱり高い壁がある、と思っとくほうが安全やろ。 Ruby なら、WSL から、1-liner で、 Rubyで作られた遅いウェブサーバー、WEBrick が起動する index.html が、Windows 側のC: ドライブにあるとすると、 cd /mnt/c/〜 で、Windows側へ移動して、 または、index.html が、linux 側のドライブにあるとすると、cd で、そこへ移動して、 ruby -run -e httpd . -p 8080 これで、Windows側のブラウザで見れる http://localhost:8080 つまり、プロジェクトが、Windows/Linux側のどちらにあっても、Windows側のブラウザで見れる Webサーバーを経由すれば、ファイルが地球の裏側にあってもふつうに見れるなー。w Linux 側のフォルダ内を公開した、Linux側のサーバーに対して、 Windows 側のブラウザのlocalhost で見れるんだよ!! >>319 >>321 返信ありがとうございます。 すみませんが、selectrow_arrayrefが最初の1行しか返さないということは知っています。 そうではなく、結果(リファレンス)を変数に入れてから再度同じステートメントハンドラでselectrow_arrayrefを使用すると、リファレンス実体の方が書き換わってしまうので、1回目の結果が失われてしまうということを言いたかったのですが…。 サンプルとして'パラメータ付きクエリ'と書きましたが、複数行を返さない単純な「SELECT ?」でも再現します。 >>335 同じ変数を使い回しまくって、パフォーマンスを落とさないためやないの? GCのないPerlならたいしてかわらんやろけど。 >332 ウェブサーバーならbusyboxでよくね?w 数MBのメモリで動作する >>335 クエリ結果を保持してるのはステートメントハンドラオブジェクトの方でパフォーマンス優先のためにその内部変数のリファリンスを返すのが*_arrayrefって考えればいいかな んでselectrow_arrayrefの第1引数に文字列を渡したときは内部で毎回prepareされるので後から実行しても書き変わらないと 第一引数に$sth渡せるんだって思ったね 文字列しか渡したことないし Perlはいまだに知らないことがある >>339 そうですね。 DBI.pmで第1引数がリファレンス(ステートメントハンドラ)ならそのまま使用、そうでなければprepareしているところまではわかったのですが、その後の流れは同じのようでしたし、Driver.xstまで解析するのはやめておきました(^^;) >>340 そういう時は How dare you? と言う。 関連付けの仕組みを知らない人がいるのかな? 単にレジストリに、この拡張子はこのコマンドで実行するって書くだけなんだけど つまりcmd。exeから実行できるものは全て 同じやり方で関連付け作れるってことね それはただの起動のしくみでしかない。 実際の動作は高い壁で分離されてるといって過言でないものをいっしょくたにはできまい。 そもそもダブルクリックできるなんて 起動の仕組みなんだから、起動の仕組みでしか無いと言われても その話をしてるんですよとしか言いようがないがw だからエクスプローラからWSLにあるファイル見る方法教えてくれってw それは見れる \\wsl$ エクスプローラからしか見れないのが問題 ダブルクリックてエクスプローラーの話じゃん エクスプローラーから見れるなら、ダブルクリックして開ける。 その証拠にテキストファイルだって開けるだろ active perlのcryptのsaltにasciiでない文字を渡すと止まるんだけど何で? >>355 理由を聞いてどうするんや? 文字コードとかややこしいから、対応してないんやろ。 暗号化って、base64 とかだろ。 ascii だけだろ Ruby なら、こういうやつだろ module SecureRandom https://docs.ruby-lang.org/ja/latest/class/SecureRandom.html >>358 わかってもなにもできんくせに ゴミクズ >>355 ここに書き込む前に、perldocを嫁 If using crypt on a Unicode string (which potentially has characters with codepoints above 255), Perl tries to make sense of the situation by trying to downgrade (a copy of) the string back to an eight-bit byte string before calling crypt (on that copy). If that works, good. If not, crypt dies with Wide character in crypt . おそらく、crypt はPOSIXの仕様に合わせているから、こうなるのではないかと思う。 128-255を渡しても止まるんだけどね エラーが出るとかじゃなくて異常終了する 仕様だとは思い難い 「異常終了」じゃなくて、「die」してるんちゃううんか? >>363 にもそう書いてあるやろ。 トラップしたけりゃevalしろ。 die すると何かエラーメッセージ出しておとなしく終了するんじゃないのか? windowsに怒られとるぞ この言語はなにが起こるかわからんので基本evalで囲わないとやってられませんね トラップでevalってなんだっけ?w Perlやめてから結構立つから忘れた。 なんかそんなのあったなwww 今?Perlからシェルスクリプトに回帰していますがなにか? >>368 これ https://perldoc.jp/func/eval eval BLOCKってやつ try catchみたいなもん エラーが返るならtryできるだろうけど、試してみたら異常終了するようなもんも避けられるのか? man にはどう書いてあるの? Perl の crypt じゃなくて C のライブラリの方だよ。 WindowsだしActivePerlのようだし、何がおきてもふしぎじゃないな。w Windows10、activeperl 5.20なんだけど、次のコードできちんと動く。何が問題なのか解らない。 $res = eval {crypt('aaa', 'ppp')}; print "1. $res\n"; $res = eval {crypt('aaa', 'あ')}; print "2. $res\n"; $res = crypt('aaa', 'ppp'); print "3. $res\n"; $res = crypt('aaa', 'あ'); print "4. $res\n"; __END__ 1. ppFj4OYENOP9c 2. 縺VSnoxRf90hw 3. ppFj4OYENOP9c 4. 縺VSnoxRf90hw 検索が遅い いろんな条件に対してファイル全体を検索、ということをする時に、 OSのキャッシュに頼って毎回 `grep` する方が速い メモリに読み込んで検索すると負ける ループで$data[$i] =~ /$pattern/ した方がまだ速くて、 grep {/$pattern/} @data するともっと遅くなる 大量一括検索の高速化のテクニックみたいなの何かあるのかな MCE::GrepはCPUの使用率は上がるけど遅くなった grepよりは正規表現の処理のあたりが時間かかってるんだと思う 感覚的にはもっと高速でも全然おかしくない感じなのに 100MBのファイルからパターンに合う行を全部抽出するのに1秒かかるくらいの感じ で、パターンが250もあるから、コーヒーが飲めるくらい待たされる 俺だったらgrepでやっちゃうなぁ 結果はファイル経由で >>376 qr//で事前に正規表現をコンパイルしてみたら? 同じパターンで繰り返し検索するのではなくて、 いろんなパターンで同じ対象を検索するので、コンパイルはできない でも、パターンのリストは実行前に確定しているので、 qrで作ったものを配列に持たせておけば速くなるだろうか もはや perl の能力を超えているな C とかで書いた方がいい パターンの内容にもよるが、flex で書いて Inline::C で呼ぶという方法もある。 色んなパターンで? grep -f でパターン読ませてやるのと同じか? 素の Perl は NFA だけだから、どうしても速度的には不利になる。 パターンが250もあるなら尚更だ。 grep との差はPerl と C の差はもちろんあるだろうが DFA でできるパターンなら、その差が大きいと思う。 linuxだったら素直にgrep呼べばいいだけだけど、 windowsだと素性が良くて高速なgrepを探すところでまず困難がある さらに、grepに引数を渡すところにもエスケープ文字の困難があって、 結果の受け取りにも文字コードの困難が そういえば awk は DFA じゃなかったかな。 perl の Memoize は関数全体に掛けるようですが、 ruby の @memo、javascript の memo の変数に掛けるのは新し目の使い方でしょうか >>388 WSLのUbuntuだとどうなのだろうか? あれ遅い? NFA でなければならない理由がないなら DFA にするだけで速度 1000 倍は堅いかも。 でも Perl のままでも正規表現のチューニングは可能だ。まだやってないならね。 実際に使ってるパターンを見せてもらわないことにはなんとも言えないが。 win8.1のサポートが終わった頃に思い出したら使ってみよう @array = ($str =~ /(PAT1).+?(PAT2).+?(PAT3)/g); みたいにすると、パターン3つ分が配列に入るけど、他にもマッチするとそれも続けて入る できれば2次元配列になって欲しい そんな技はある? そういうことをする時のセオリーはスカラコンテキストで $str =~ /\G$pat/g 可能? $str = '1a2b3c1x1d2e3f1g2h3i'; を与えられて [[a, b, c], [d, e, f], [g, h, i]] を得るにはどうすれば my @arr = (); while ($str =~ /\G.+?([a-z]).+?([a-z]).+?([a-z])/g) { push @arr, [$1, $2, $3]; } [[a, b, c], [x, d, e], [f, g, h]] になっとるよ でも判った 普通に$1使えばいいだけか 結果を一つずつスカラに取るんだと思ってた /\G.*?1(.)2(.)3(.)/g これがやりたかったこと 結局コードはあんまり変わらなくて、ループで push @array, ($1, $2, $3) にするか、後で splice(@elements, 0, 3) を使っていくかの違い パターンを3つから4つに増やした時に、 $4を追加するか、3を4に増やすかのメンテはやっぱり必要 いきなり2次元配列が得られるスマートさからは劣る どうやら今回は必要ないみたいだけど事前にグループの個数が 判らないという前提なら @- とか見ればいい。 あるいはグループに名前を付けて %+ を使えばいい。 全部ここに書いてあるよ。 https://perldoc.jp/pod/perlretut Perlで、とある配列を指定した要素数ごとに別の配列リファレンスに分割する処理をList::MoreUtilsモジュールで書き直してみた https://perl48.hatenablog.com/entry/2018/08/19/005304 ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる