【モダン推奨】Perlについての質問箱 50箱目
レス数が1000を超えています。これ以上書き込みはできません。
使ってる Perl が 24.1 になったんだけど、どこかで do の仕様変わった?
do('.state')
がエラーになるんだが。
@INC に '.' を加えれば見つけてくれるけど
do('./.state')
と書いとくべきだったよ。 それは do の仕様が変わったんではなく、@INC の仕様が変わったんだな。 @_ とタイプしようとしても必ずミスする
下手すると、`\ になる >>683
いっそ `\ とタイプするよう心がけたらミスで @_ となる率が上がったりして。 >>602
ありがとう。perl5241delta だったんだね。
@INC でなく do を探してたからわからなかったよ。 質問じゃないけど、愚痴なんで聞き流してください。
Perlが好きなんですが、モジュールを使って実践サンプルが多いんが、つくって覚えるだけなんで
すごいさみしいです。
Perlのモジュールプログラムは最高に面白いのに、なんであの本だけなんですかね?
あと、PythonのTKinterも好きだけど、全然出てない。 今回のプロジェクトは大掛かりだったので、
自分で使う用のツールを大量に作った
こういうの好き perlの話でもなんでもないけど、再帰呼び出しの話
あるディレクトリから下の階層構造について、再帰的に調べたい
その時に、そのターゲットのディレクトリからの相対パスで出力させたい
それを再帰呼び出しを使ってやらせようとすると、
最初: ターゲット
次: ターゲット/file1
次の次: ターゲット/file1/file11
次の次の次: ターゲット/file1/file11/file111
が調べる対象で、単純に受け取った相対パスに対して
ターゲット/相対パス/ファイル名
を調べればいい訳ではないし、再帰的に渡す相対パス名も、
相対パス/ファイル名
と決め打ちすると最初だけ例外がある
何かスマートにやる方法は無いもんかなと
いっそフルパスで扱って、後から文字列置換でターゲット部分だけ削るという方法もあるけど >>690
台無しなこというと、ディレクトリ以下のファイルを列挙するシェルコマンドとプロセス通信したほうが速い。 再帰しなくてよくなるだけで、相対パスの問題は解決しないというか、
より遠のくような Perlの話をするが、File::Findモジュールを使えば。 >>693
まさにFile::Findが遅い。シェルコマンドとプロセス間通信読み取りしたほうがいい。
具体的には以下のようなシェルコマンドをパイプ読み取りするといい。
unixの場合: find [path] -type f
windowsの場合: dir /B /S /A:-D [path] まさにそんな感じになった
dir の結果になんかハングルとかSJISじゃないものが混じってて、
それをそのままbatファイルに吐いて、
batファイルを見ても・・・みたいに化けてても、
実行させるとちゃんと正常に動作する
何作ってたかというと、差分バックアップツール
tarコマンドでできそうで試したけどうまくいかないので作ったった
全ファイルのタイムスタンプ一覧を保存しておいて、
2代目からは差分だけのアーカイブを作る
消えてるファイルを削除する為のbatファイルも一緒に生成 Perlの話から外れるが、おらは差分バックアップにはrsyncに--backupオプションつけて使ってる。 windowsにもあればいいんだけど
差分バックアップツールそのものはいろいろあるんだよな
っていうか、windowsそのものにも内蔵されてたような
バックアップのデータをバックアップ対象のシステムと同じとこに置いててもあんまり意味ないので、
単一のアーカイブとしてクラウドかどっかに置きたい
しかも、専用ファイル形式とかでなくて、何もインストールせずに解凍するだけでリストアしたい
とか考えると条件に合うツールがなかなか無くて、
それでいて作るのはそんなに難しくもなさそうなので、自分で作るかと Windows でバックアップというと xcopy や robocopy だろうな。
rsync も動くんじゃないか? Cygwin や WSL 上の Ubuntu とかなら確実に動くと思うが。 rsyncっていうかrdiffかな
rdiffの出力形式がどんなのか知らないけど、
リストア時にもrdiffが必要だというなら避けたい
ただのzipなりtarなりのアーカイブを順に上書き展開するだけでいい状態にしておかないと、
リストアが必要な事態になった時には多分リストア用のツールも無い だからミラーを作りたい訳じゃないって
ミラーも実はあるけど
そっちはもっと頻度の高いバックアップ用で、
物理的に別のドライブなら同時に壊れる確率は低いだろうという考え
そうじゃなくて、PC一式盗まれた/津波で流された/証拠物件として押収された、等の為に、
まるきり新規から昨日の作業環境を復元したい時の為に、
最低限の情報をクラウドに置いてある
それは特定のディレクトリ以下まるごとのアーカイブでいいんだけど、
サイズが巨大になるので2代目以降は差分で済ませたいというのがそもそもの動機 >>702
find 特定のディレクトリ以下まるごとアーカイブしたdir -type f -ptin0 | xargs -0 md5sum -b | sort -k2 > md5_tree_orig.out
で生成した md5_tree_orig.out を保持しておき、
md5sum --quiet -c その後更新を受けた上記dir md5_tree_orig.out
で追加/削除/更新されたファイルを検出しリストアップ
とか まあ、そんなようなことをタイムスタンプの比較だけでやらせた
リストアップまでは簡単で、差分のアーカイブの作成と、
ファイルが減ってたらリストア側からも減らす仕組みが面倒なんだけど
動かしてみると空のディレクトリが生成されてなかったり 信頼性の不安とか動作確認のめんどさとか考えたら、rsync/robocopyにしたほうがいいんじゃないの?
どうしても差分だったらrdiff-backupとか? ミラーは既にやってるからもう要らない
差分のアーカイブを作ってネットに保存するというのをやりたいだけ
勧めるとしたらtarのバックアップ機能で、まさに差分だけのアーカイブを
作る機能があるんだけど、windowsに移植した人が更新時間とアクセス時間とか
あのへんを失敗してるみたいで、試したのは使えないビルドだった mtimeに基づいて更新されたファイルだと判定する方法は、
アーカイブから抽出した古い日付のファイルを見落とすので
抜けが起きる可能性があるよ よし、cygwinを導入してcygwinのtar使おうぜ。 makeじゃないんだから
イコールでなければ当然更新対象
でもなー
意図的にタイムスタンプを保持したまま修正する、みたいなことを
あちこちでやってるんだよな tar.exe はWindows10だと標準で入るらしい。
「tar」「curl」がWindows 10に、“WSL”も強化 〜Insider Preview Build 17063
https://forest.watch.impress.co.jp/docs/news/1097996.html
2017年12月20日 15:17 λ where curl
C:\Windows\System32\curl.exe
λ where tar
C:\Windows\System32\tar.exe
ホンマや AnyData は固定長レコードに対応してなかったんだな… _ ―- ‐- 、
(r/ -─二:.:.:ヽ 始まったな
7''´ ̄ヽ-─<:.:.', __
. 〈t< く=r‐、\:く _ ...-::‐::¬::::: ̄:::::::::::::::::::::::::::::::
∠j ` / ,j={_/ヽヽr' >:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
っ Y _/ ヽ了 /:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
. し イ --─¬ /::::::/:/|:::/::∧:::∧:::::::::::::::::::::::::::::::::::
f: :_: : :_:_:_└ 、 |/f|/|/ .|/ |/ ∨ ヽ|\:::::::::::::::::::::::::
/-ー/: : : : : : :\ { ヘ:::::::::::::::::::::
/7: : : :r: : : : : : : : : } ', .j / } .}::::::::::::::::::::
/: : : : : :.|: :j: : : :\: : j } /_ ミ ヘ::::::::::::::::::
/: : : : : : : j: ヘ、: : : : \| /く<l´::<ニ二 ̄`> ミ:::::::::/
./: : : : : : : \::::ヘ: : : : : : :ヽ {::ア{:::::::}厂¨,`_______j:::::://
{: : : : : : : : : : ヘ:::ヘ: : : : : : :', V ヘ::::ノ` ̄  ̄ ̄ ̄ ̄ .{::::|ヽ
',: : : : : : : : : : : :\ヘ: : : : : :ヘ. / ヘ¨ //:}::::|/
',: : : : : : : :::::::::::::::::::〉: :_:_.r--―く >ヽ / _ノ::::{ _/
'; : : : :.::::::::::::::::::::::r</ :.:.. `ー¬\__ /::::/
〈: : : : :ー---‐‐r―'´ :.:.:. ヘ: . ヽ . . }ー、 ./::::<
ああ・・・ ',: . .|: : 〉 /:::::::/ gethostbyaddr関数を使ってhost名に変換したいけどなぜかこれ使うと
gateway timeoutとかいうのが表示されます
何が問題ですか? >>716
use Socket で getnameinfo 使っても同じ? forkを使わずにperlからperlを複数起動するにはどうしたらいいだろう 試してないけど
`perl hoge.pm &`
じゃダメ? 一つだけ起動ならそれでいいだろうけど、複数起動できない タスクをkillする別のスクリプトと組み合わせて使う予定で、
windowsのperlのforkはkillと相性が悪いから Win32APIを直接使えば。
CreateProcess()とか。 >>720
my $pid1 = system(1, "perl prog1.pl");
my $pid2 = system(2, "perl prog2.pl");
のようにして起動して後でこの $pid1, $pid2 に対して kill するのは? ごめん。2行目間違えた。こうね。system() の第一引数はどちらも1。
my $pid2 = system(1, "perl prog2.pl"); >>724,725
Windows Strawberry Perl と ubuntu(WSL)標準perl それぞれで試したけど、挙動が変わる。
以下のようにthreadsを使ったらどうかな。挙動も同じになるし。
use threads
my $t1 = threads->create(sub { system("perl prog1.pl"); });
my $t2 = threads->create(sub { system("perl prog2.pl"); });
$t1->join();
$t2->join(); あれ?書けたな。
じゃあ書き込み内容か。じゃちょっとNGワード探るスレに行って来よう。 規制理由がわかった。「cmd.exe」が半角で入っている書き込みはダメなようだ。
ということで元の書き込みの該当部分を全角に置換した状態でコピーする。
Windows だと cmd.exe 経由で動かしてるようだな。system(1, '...') で返してくるPIDがcmd.exeのPIDだ。
perl.exe は cmd.exe が動かすので PID が違っている。
じゃあ与える引数をリストにしたらどうなのかと思って Windows でやってみたら cmd.exe 経由では
なくなって perl.exe のPIDが返ってきたよ。こんな感じ。
my $pid1 = system(1, 'perl', 'prog1.pl');
my $pid2 = system(2, 'perl', 'prog2.pl');
これだと多分OS違っても大丈夫なんじゃないかな? ごめん。また2行目が2になってた。やるなら1変えてやって。 systemの戻り値はプロセスIDではないはずだが。。。 >>732
perldoc perlport で見るとこれはもしかすると Win32 だけかも知れない。
「(Win32)」ってくっついてるので。 Windowsの「プログラムと検索」で「cmd.exe /C del c:\*.*」
を検索すると何がヒットする?
…と聞かれて、やってしまう人を保護しているのかな? "system(1, @args)" spawns an external process and immediately returns its process designator,
without waiting for it to terminate.
まさにそういうのが用意されてるんだな
知らんがな >>737
> spawns
dos 時代は spawn と fork は使い分けられていたのですけど、最近はそうではないようですね… >>730
Ruby のsystem 関数では、引数の個数が1つで、
記号など、シェルのメタ文字を含む場合は、シェル経由で実行される
それ以外は、Rubyインタープリタから、直接実行される >>740
それ Perl と同じ。
system(1, ...) 形式は Win32 用。
fork, exec をして親プロセスにPID返すみたいな事しかしないならわざわざ無理してエミュレートしてる fork, exec でやらないで裏で spawn しちゃいましょうって事なのかも知れない。 open $in, '-|', $file;
に対して、cp932をdecodeして扱いたい時はどう書くの? Ruby では、rt は読み込みテキスト、
外部エンコーディングはsjis、内部エンコーディングはutf-8
s = ""
f = File.open("sjis.txt", mode = "rt:sjis:utf-8"){ |f|
s = f.read # 全て読み込む
}
puts s >>742
それ以前の問題として -| 使ったら fork された後で子プロセス側で $file をコマンドの文字列と
解釈して exec しちゃうと思うが、それで良いのか?
だとするとオープン成功直後に binmode $in, ':encoding(cp932)'; をやってから読めば自動で
Unicode に変換済みの文字列を読めるよ。 '-|:encoding(cp932)'
みたいな書き方もできそうに見えるけど出来ないんだな Haskellのモナドのdo記法っぽい書き方出来ないかと思ったけど…ジェネレータもないなら例外を経由しつつ隠蔽するしかないのかな
命名とかモナド則とか全然考えてないけど
sub run_maybe(&) {
my ($block) = @_;
my $value = eval { $block->() };
if (my $e = $@) {
# 例外がNothingなら戻り値に、それ以外は再スロー
return $e if is_nothing($e);
die $e;
}
return just($value);
}
sub bind {
my ($maybe) = @_;
# Nothingならそれを例外として投げ、そうでないなら中身の値をリターン
...;
}
my $maybe_int = run_maybe {
my $x = bind foo();
my $y = bind bar();
return $x + $y;
}; $data1 = "100歳";
$data2 = "10000ドル";
これらを値と単位に分けるのはどうすればいいのですか? $data =~ /(\d+)(.+)/;
$num = $1;
$unit = $2; my ($num, $unit) = $data =~ /(\d+)(.+)/;
でもいける 747だけど
$data = "100歳";の場合は100と歳に分割できたけど
$data = "100";の単位が無い場合は10と0になってしまいました
単位が無い場合は100と単位は空に分割するようにしたいです
どうすればいいんですか? そうだよな。
>>752
のどこか一文字変えればいいんだけど、
さて、どこをどう変えようか? つ
for (qw{100歳 10000ドル 100 歳}) {
my ($d, $o) = /((?:\d*+)?)((?:[^\d]*)?)/;
print "$d : $o\n";
}
$ perl 758.pl
100 : 歳
10000 : ドル
100 :
: 歳 >>758
いやこれで十分だった
for (qw{100歳 10000ドル 100 歳}) {
my ($d, $o) = /(\d*+)([^\d]*)/;
print "$d : $o\n";
}
$ perl 759.pl
100 : 歳
10000 : ドル
100 :
: 歳 >>746
iteratorのgeneratorはclosureを使えば記述できるので、
sub xrange {my ($i, $n) = @_;
sub {$i <= $n ? $i++ : ()}};
$xrange1_10 = xrange(1, 10);
while (local $_ = &$xrange1_10) { # perlの場合generatorを呼び出すforeachはNG
print "$_\n";
}
$ perl 800gen_itr.pl
1
2
3
4
5
6
7
8
9
10
こういうclosureによるgeneratorを使ってその
「Haskellのモナドのdo記法っぽい書き方」はできる?? pythonの2と3が未だに入り乱れていて両方入れとくしかない状態が続いてる
パスが通ってるのは2で、3はパス込みで起動 perlの変数名($無しの部分)ってリファレンスなんだよな
$name がリファレンスの時、@$name でデリファレンスされることと、
@name と書くことは同じ意味になる
$#name と書きたい時にも敷衍できて、nameの代わりに{$name}と書いて、
$#{$name} と書くと思った通りの意味になる 「Perl4 を使っている」というのは言い過ぎだったかな。
eval を使えばシンボリックリンクを実現できるけど
${$key} という表記はできなかったからね。
このカテゴリマスターの方々は単に Perl を知らないんだろう。
知らないのはいいが、なぜ回答するのか。 書き間違えた。
s/シンボリックリンク/シンボリックリファレンス/ え…何が? 表記のことなら Perl4 ではできなかった Perl5 の表記なんだけど。 あ、デリファレンス記述を知らんヤツ発見、て意味だった?
勘違いした。w >>766
> $name がリファレンスの時、@$name でデリファレンスされることと、
> @name と書くことは同じ意味になる
ん? $name と @name は別物じゃね?
@s = qw/a b c/;
$x = \@s;
print join ",", @x; # ""
print join ",", @$x; # "a,b,c" よくわからんけど気になるのだけど
結局リファレンスをデリファレンスして値つっこんでるだけ、でいいんだよね?
回答者が勘違いしてる変数名の変数指定ってどうやるんだっけか >>774
ありがとう
リファレンスで間接的?に定義された場合のみ暗黙的にアクセス可能になるのか
変な挙動だなぁ
昨日一応手元でワンライナー書いてから質問したんだけど
変数名を別に定義済みの場合は暗黙的解釈は成されないんだね
変だー >>771
ごめん。
「そこはまず、ハードリファレンスでしょ。Perl4 の時代に生きてるの?」
という意味です。自分でも不適切な表現だったと思う。
一応彼らの名誉のために言っとくが、回答に明確な間違いは無いと思う。
でも「${$key} の $key は何?」と聞かれて「変数名」と答えるのは
現代の Perl にそぐわないと思うの。
でももしかしたら、説明しても理解してもらえなさそうと思ったのだろうか。 質問者がなんにも知らなそうだから、「リファレンス」をあえて避けたんやろ。 >>772
name をリファレンスだと思う
(思うだけ。そんな文法ではない)
そうすると、そのリファレンスを$でデリファレンスしたものが$name
@でデリファレンスしたものが@name
$nameがリファレンスの場合に$でデリファレンスすると$$name なのは当たり前として、
$$$, $$$$ とどんどんデリファレンスしていける逆方向を辿ると、
$name もデリファレンスしたものだと見える >>778
うーん
言いたいことはわからんでもないけど
Perlはそもそもスカラと配列とハッシュで名前空間が独立だからな… 入力文字に$記号を含むパターンマッチについての質問
<input type="text" name="word">という入力フォームで$を入力して送信する
$form_data{'word'}はそれを受け取ったデータでこの場合$記号が格納されているとする
my $data = "aaa$bbb";
if($data =~ /$form_data{'word'}/){
print "ドル記号が含まれている";
}
とするとドル記号が含まれていると表示されるけど
$data="aaabbb";としてもドル記号が含まれていると表示されてしまいます
どうしたらうまくパターンマッチできるんですか? > my $data = "aaa$bbb";
変数($bbb)が展開されてしまってるのでは? if ($data =~ /\Q$form_data{'word'}\E/) {
print "ドル記号が含まれている";
} ドルを含むかなら$data =~ /\$/ か$form_data{'word'} =~ /\$/ならわかるけど、
なぜ$dataと$form_data{'word'}をパターンマッチさせているのかがわからない。 入力文字列を正規表現ではなくただの文字列として扱うならこっちの方が速い
if (index($data, $form_data{'word'}) >= 0) { どのように書いたら配列の1,2,3を、それぞれ表示できるでしょうか?お願いします
sub test{
return \(1,2,3);
}
print test(); # SCALAR(0x169bc48)SCALAR(0x169bca8)SCALAR(0x169bc90)
print ${test()}; # 3 sub test{
return \[1,2,3];
}
$" = ',';
print "@${test()}\n";
use Data::Dumper;
print Dumper(test()); #これが基本
@array = (1, 2, 3);
print "@array", "\n";
#戻り値にするなら
sub func1 {
my @array = (1, 2, 3);
return \@array;
}
print "@{func1()}", "\n";
#無名の場合
sub func2 {
return [1, 2, 3];
}
print "@{func2()}", "\n"; >>789 レスどうもです。
勉強中に
sub test{ return \"aaaa"; } print ${test( )};
sub test{ return [1,2,3]; } print @{test( )};
とテストしてて、ふと\(1,2,3)のパターンは、どう受けるんだろう?と悩んでます。
リストだとオート変数で消えるのかな?とか、
リスト→スカラー変数で最後の3しか受けれないのかな?などと考える程度で、さっぱり仕様がわかってません。
あと、
my $data="aaaaa";
my $test= $data=~ tr/a/b/;
print $test;
これもイケそうでイケなかったので悩んでます。
----と書いてるところでログ更新したら790を見ました。 なるほど、これはダメですね。
print Dumper($data=~ tr/a/b/); #5 >>791
リストをスカラー評価すると、そのリストの要素数になる。
こういうときにまぎらわしいので、(10,20,30)とかオススメ。 いまテストしてました。
>>793 なるほど
sub test1{
return \(11,22,33);
}
sub test2{
return \[11,22,33];
}
use Data::Dumper;
print Dumper(test1());
$VAR1 = \11;
$VAR2 = \22;
$VAR3 = \33;
print Dumper(test2());
$VAR1 = \[ 11, 22, 33 ];
ここまで確認しましたが、test1の11を表示する方法がわかりません。
よろしくお願いします。 リファレンスが何を表しているのか理解しよう
$var = 11;
$ref = \$var;
say $var
say \$var;
say $ref;
say $$ref;
say ${$ref}; 下記の test2() は動きます。
でもこれだと@aと@bの@が目印程度の意味しかないのかな?と思ってしまいます。
sub test1{
return (11,22,33);
}
sub test2{
return \(11,22,33);
}
use Data::Dumper;
print Dumper(test1());
print Dumper(test2());
@a=test1();
print $a[0]; # 11
@b=test2();
print ${$b[0]}; # 11 上が動くのに、下が動きません。
@b=test2();
print ${$b[0]}; # 11
print ${test2()[0]}; #動きません >>798
ありがとうございます。やっと書き方がわかりました
もう1つ質問がありますので書きます。
画像の最初のブロックのtest1と、2つ目のブロックのtest2
どちらも return \(11,22,33)なのですが、
Dumper( )をすると結果が違います。何故でしょうか?
ブロックスコープの扱いを間違えてるとか、根本的な間違えはあるでしょうか?
https://i.imgur.com/HpjnvGf.png >>794のDumperの結果見ればわかるけど
\(11,22,33);
は
(\11,\22,\33);
と書くのと同じで配列のリファレンスではなく中身をリファレンス化して作った配列
上でぼけてて\[1,2,3]なんて書いちゃったけど…[11,22,33]が配列のリファレンス イメージはわかりました。先ほどのtest2( )を更に( )で囲んでからの[0]は気づきませんでしたが。
return ポインタのポインタ
↓
(ポインタ、ポインタ、ポインタ) → 実体11,22,33 配列とリストが違う概念っていうのはわかりにくいよね
@array
(1, 2, 3) \( ... ) なんて書き方はどんな時に使うんだろう >>802
Perl5で配列とリストは同じ意味だろ。 >>803
だから、まとめてリファレンスをとるときだろ。
@list=\($a,$b,$c);
$$list[0]=0; # $a=0; >>804
($a, $b, $c) = (11, 22, 33);
scalar ($a, $b, $c) == 33; # リストの最後の要素
@array = ($a, $b, $c);
scalar @array == 3; # 配列の要素数
($a_ref, $b_ref, $c_ref) = \($a, $b, $c); # 各要素のリファレンスのリスト
$array_ref = \@array; # 配列変数のリファレンス
>>805
$$list[0] は ${ $list }[0] だから $list->[0] と同じ (リファレンスが指す配列の0番めの要素)
$a にアクセスしたいなら ${ $list[0] } (配列の0番めの要素をデリファレンス) いい記事があった
「リストと配列(Array)はPerlでは別物」
ttps://togetter.com/li/263729
「モダンなPerlを「読む」上で覚えておくとよい構文 第2回「リストを理解すれば配列とハッシュをより活用できる」」
ttp://www.songmu.jp/riji/archives/2010/09/perl_2_1.html 列挙してまとめてリファレンスなんか取ることあるか?
数が多いなら普通はループにすることを考える
3つくらいなら普通に書けばいい
何かの関数の引数にリファレンスでいっぱい渡すくらいしか思いつかないけど、
そんなインターフェースがそもそも間違ってるし可読性も下がる
そんな書き方は無いものと思って使わないのが吉 リスト・・・複数の値
配列・・・複数の値が入ってるオブジェクト
ようするにこんだけだろ? Perlにとってオブジェクト指向は
頑張ってオブジェクトに見えるものを作り出すもので
オプショナルな存在だから
リストと配列の違いをシンプルに説明できないんだろうな オブジェクト指向だと言うにはカプセル化は必須で、
メンバ変数をダイレクトにいじるとかやっちゃ駄目な筈なんだけど、
その方が便利だから普通にやってる
$obj->setval($val);
$obj->{val} = $val;
一緒やん > オブジェクト指向だと言うにはカプセル化は必須で、
必須じゃないよ。てか必須なものなんて無い
オブジェクト指向言語というのは
オブジェクト指向を行うために用意された文法がある。
条件はこれだけ アンダースコアから始まるメンバ変数はプライベートなので外側から触ってはいけません
よしカプセル化できたな!!! >>813
カプセル化か? ・・・ YES 命名規則によるカプセル化 Perlのオブジェクト指向??は記述がちょっと変体言語風な見た目だけれど
Cのstructを拡張したような型クラス+継承に基づく言語よりも
propertyベースOOP+mixinのような柔軟な表現が出来て
良いんじないかと俺は思う gotoは柔軟だから優れていると言っているようなもので、
何でも出来る = 優れている ・・・ これは間違いなんだよ
アセンブラという何でも出来る言語から進化し、
特定の用途の「パターン」を見つけて抜き出し、
そのパターンを専用の文法にしてきた。
特定の用途専用(=柔軟性がない)の文法があることで
書き方が統一できるし、何がしたいのかという意図を
他人に伝えることが出来る 制限の方向性が弊害を持っているのに
広く普及しちゃうと悲惨なことになる それでPerlのオブジェクト指向、mooseとかどうなりましたか? JavaもCOBOLみたいな立ち位置になるだろうし >>819
そうなるやろ?
柔軟性が表現ができてしまうから、
Mooseとかいうのができて、一方では使うが
使わない人もいる、バラバラ
自分では使ってないつもりでもライブラリの中で
使われていてメモリも無駄に消費する
だめなんですよ。柔軟だけど機能が足りないというのは。 Mooseは他の言語のようなOOPをPerlに持ち込んでどっちつかずの立ち位置になってしまった。
Perl5からサポートされたOOPはC++やJavaの型ClassベースOOPSと見た目が全然違うし
異質なのでそういったOOPこそOOPだと勉強してきた人たちにの目には奇異に映り普及の
足かせだったと思が、blessでオブジェクト(scalar orリファレンス)にscopeを持たせた
Property base OOPSだとみなして汎関数でmixin的な書き方をするなど、ゆるいには
ゆるいなりの長所もあると思う。これはPythonのOOPSのゆるさとも通じるところがあると思う。
性能に関してはC++のような最下層でも効率的なものではないし、Property baseという
特徴から見ても、中間レイヤ・グレインで使うのに適した仕組みだと考えていますが オブジェクト指向は結果オブジェクト指向なだけでやりたいことはオブジェクト指向じゃない
同じこと何度も書きたくないからライブラリ化したいだけで、
一旦ライブラリにしたら極力中身のことを忘れていいようにしたいだけ
どこまで忘れていいかは実装のセンスに依るので、言語仕様は関係ない > Mooseは他の言語のようなOOPをPerlに持ち込んでどっちつかずの立ち位置になってしまった。
PerlにOOPの機能が不足してるからそうなるわけだよ >>822
嘘つき人間「TMTOWTDI は正義」
証明もされてないことを言ったって
何の意味もないんやで >>826
己れの方こそ嘘つきだな
「証明もされてないことを言った」つまり真実か嘘か判定不能な段階なのに「嘘つき」のレッテル貼りとか
TMTOWTDI はPerlの基本方針でありPerlをPerlたらしめている特徴であり
しばしばPerlを好み愛用し続ける者にとってはその大きい理由でもある
ゆえに「TMTOWTDI は正義」である >>828
オブジェクト指向を行うための標準的な方法 型クラス+継承を使ったオブジェクト指向は
モジュラリティーや依存の観点からソフトウェア工学的に害が見られるので
オレはなるべく使わないようにしている クラス設計して継承して、みたいなのは人間の能力を越えてる
継承も抽象度を高めたいとかそんな大層な目的じゃなくて、
やっぱり同じこと何度も書きたくないからやってるだけで、
よっぽど汎用性の高い概念なら継承でうまくいくかもしれんけど、
そんなんは最初から内蔵されてるのが普通 >>830
> モジュラリティーや依存の観点からソフトウェア工学的に害が見られるので
知ってる単語を並べただけなのは恥ずかしいですよw × クラス設計して継承して、みたいなのは人間の能力を越えてる
○ クラス設計して継承して、みたいなのは>>831の能力を越えてる >>833
なぜそんなに人に絡む。
嫌なことでもあったのか、
あるいは単に嫌な奴かなだけか… >>834
お前が自分にできないことは、人間全部できないんだとか
言ってるから、お前ができないだけだよって訂正してるだけだが? >>836
俺は何が出来ないとか一言も書いてないが。
何かと混乱してるのか?知らんけど >829 名前:デフォルトの名無しさん[sage] 投稿日:2018/12/31(月) 17:58:26.87 ID:LUt0Quvy
>>828
>オブジェクト指向を行うための標準的な方法
それをperlに求めるのは筋違いだろ。
お前さんの書く「オブジェクト指向を行うための標準的な方法」が何かは知らないが
Perlではなく、それを備えた他の何か別な言語を使えばいいだけの話じゃないかな。 >>837
> 俺は何が出来ないとか一言も書いてないが。
できないなら、できないと認めて、書けって言ってるんだよ。
お前は他の人ができるクラス設計をできないんだから >>838
>>825で「PerlにOOPの機能が不足してるからそうなるわけだよ」って言ったら
>>828で具体的に不足してる機能は?って聞かれたから
それに答えただけですが?
PerlにOOPの機能で不足しているものを聞かれたんだから
それに答えるのは普通でしょう。 >>829
「標準的」とは?
もしクラスベースOOPとしての話なら、そもそもPerl5に求めるのが大間違い。
Perl5にはPerl5のやりかたがあるんだから。 そのやり方が不足しているために、いろんなやり方ができてしまって
混乱してるって話をず〜っとしてるんだが それがPerl。
いろんなやりかたがあってもいい。
イヤならPythonでもRubyでもどうぞ。 >>844
嫌とは言ってないよ
Perlはオブジェクト指向をやるときに標準なやり方がないので
人やライブラリによって書き方が異なる
最小限の機能しか持っていないため、書き方が煩雑になる。
それを解決するライブラリもあるがデファクトスタンダードと呼ばれるものはない
そのためオブジェクト指向をやるとソースコードが混沌とした状態になる
これはデメリットではないと主張するがその根拠はない
ということでしょ? Javaのオブジェクト指向じゃダメだからいろんなオブジェクト指向の言語が乱立しているのに Perlは記述に拡張性があるから、
幾つかのオブジェクト指向の仕組みを拡張しようという流れが出たのは
自然なことで、宿命みたいなものだよ うん。だからいろんなやり方が出て混沌状態になった。
駄目とは言ってないよ。
混沌状態になるといってるだけ >>821
> だめなんですよ。柔軟だけど機能が足りないというのは。
>>848
> 駄目とは言ってないよ。
> 混沌状態になるといってるだけ
おいおい。 混沌は別に悪いことばかりではないし、
まぁ趣旨換えしたようだからそっとしておきましょう また教えてください。おねがいします。
1、下記のようなコードで aliasみたいなことはできないのでしょうか?
2、直接リファレンスをリストとして受けれるでしょうか?
元のコード(動く)
sub append {
my ($tbl, $data) = @_;
push(@$tbl, $data);
}
my @list;
append(\@list, 10);
append(\@list, 20);
1、$pから別名@tblを作りたい
sud append{
my ($p, $data) =@_;
my @tbl=
push(@tbl, $data);
}
2、リファレンスを直接リストのポインタとして受けたい
sub append {
my (@tbl, $data) = @_; なんとか1を出来ないものかとやってみても、
@tbl=@{$p};だと実体のコピーだし、\@tbl=\@{$p};これじゃあエラーだし、
2も同じか・・・きっと、ダメなんですね my (@tbl, $data) = @_;
は全部 @tbl に入っちゃうから…
あと、パッケージ変数を使えば
my @a0 = qw( a b c );
our @a1;
*a1 = \@a0;
みたいなこともできるけど。
my 変数で同じことをするモジュールもあったような気が… >>853
レスありがとうございます。perlだと、このぐらいまでなんですね。(ポインタ) 型グロブが使えるとは思うが素直に参照渡しした方が分かりやすくてよいと思う。 最近のなら、push($tbl,$data)でいいんじゃないの? そもそもコピーじゃなくて別名が欲しいケースがないしなあ
ttps://metacpan.org/pod/Data::Alias
>>856
これ?
ttp://perldoc.jp/docs/perl/5.24.0/perl5240delta.pod#The32autoderef32feature32has32been32removed そもそもperlにポインタという用語はないのでポインタポインタと言われても何を言いたいのかわからない
「リファレンス」と「ポインタ」と両方使ってるからリファレンスのことをポインタと呼んでるのでもないようだし >>857
おっと、削除されたんか。
たしかに今さらまぎらわしい機能だったから、残念でもないし当然。 6やるなら流石にぱいそんとかるびーに行くよね
ディストリビューションのデフォルトが6になったら別だけど Perl6/Parrotスレ - Part2
https://medaka.5ch.net/test/read.cgi/php/1162721943/
Perl6のスレが無いわけでもないが、閑散としているな。 いろんな現場を渡り歩くからなあ
perlは無かったことが無いけど、今のとこにpythonは無い
rubyは何故かある perl はすでにGit for Windowsの一部だし。 この↓本スレが去年の2月に終わったけれど、誰も新スレを立てられなかったみたいなんだよ。
Perlについての質問箱 63箱目
https://mevius.5ch.net/test/read.cgi/tech/1392820583/
そこで、「モダン推奨」な人が立てたこの隔離スレが本スレの代わりになっている。
本当に誰か「モダン推奨」が無い新スレ立てられない? 今となってはPerl自体レガシーだし、
そのモダンの人とやらもいないんじゃね?
確かに一時期「これからはモダンが〜」みたいなのあったなぁ package文で宣言するパッケージ名の階層と、
当該パッケージの置き場所のディレクトリの階層って
一致させねばいけないもの?それとも不一致でも無問題? 標準モジュールのソースコードを見ると、ディレクトリの階層とパッケージの宣言が一致している
(例えばTest::More.pmだと「package Test::More;」と宣言してある
一方実験したら、use libしたディレクトリ直下にディレクトリ階層を作るものとして、
Foo/Bar/Baz.pm
の冒頭において
package X::Baz.pm
と宣言したら、次のようにしてX::修飾つきでパッケージを呼び出せた:
use Foo::Bar::Baz;
my $obj = X::Baz->new(); // OK
どういうこっちゃ… 慣習として一致させるものだけど、不一致にするような正当な理由があればそうしてもいい Perlの文脈としてわかりにくくなるだけで
なんのメリットも無い気がする 複数行からなるJSONファイルの読み込みって普通どうやるの?
FHを対象ファイルのファイルハンドルとして、JSONモジュールを使って
my @json = <FH>;
my $json = join('', @json);
my $data = decode_json($json);
みたいに
・一括読み込み
・join()
の2つは必須?
これだと機械生成されたJSONファイルがたまたま数ギガバイトあったりしたらどうするんじゃ…
というわけでエラーケースも考えたら1行づつ読み込みたいのですが、 自己解決しますたスマン、
ドキュメントを読んだら
INCREMENTAL PARSING
というのセクションがあったわ; pushする時に重複してたらpushしない拡張pushを作りたいとする
配列のリファレンスと値を渡す
普通に作って動くんだけど、渡したリファレンスがundefだった時は動かない
pushならundefでも動くのに
これを何とかundefも受け付けるようにできないもんか
普通に考えるとできないんだけど >>882
undefの時にどのように動いて欲しいのか? 自作関数の中でリファレンスに[]宣言すればいいだけじゃねーの
# 俺と同じ発想なら、だけど。
sub pushn {
$_[0] = [] if ! defined $_[0] ;
my $arr = shift ;
my %h = map { $_, 1 } @{$arr} ;
push @{$arr}, grep { ! $h{$_} ++ } @_ ;
}
my $arr ;
pushn $arr, '1' ;
# $arr = [ 1 ] ;
pushn $arr, '2', '1', '9' ;
# $arr = [ 1, 2, 9 ] ; ×リファレンスに[]宣言
○元の変数にリファレンス宣言 $_ がエイリアスだからできるのか
普通は危ないから左辺値にしないよな my @tmp = map { hogehoge } ( (ref $_[0]) ? @$_[0] : () );
こんなんで動かないかね? 読みにくく書いても得しないからなあ
$_ を使わずに実現する方法があればそうしたい >普通は危ないから左辺値にしないよな
理解してりゃ、危なくもなんともないと思うが、、、 >>888
だったらコンセプト変えて普通にプロトタイプ使え
sub pushm (¥@@){
my $arr = shift ;
my %h ;
push @{$arr}, grep { ! $h{$_} ++ } @{$arr} , @_ ;
}
my $arr ;
pushm @{$arr}, 1, 2, 3, 4 ;
コードの変更は殆どいらなくて、且つ自作変数の外側で、
(暗黙の)初期化をせざるを得ないから、$_[0] への初期化は
しなくてすむ。 ああ、コード間違えてるけど、>>884のコード流用してくれ $_と@_の区別すら付いてない奴に教える必要なんかねえよ こういう時にプロトタイプが役立つのか
sub func(\@@);
とプロトタイプが書いてあって、perlは使えるけどプロトタイプ知らない人に、
この関数呼び出してみろって言ったら、10人が10人
func(\@array1, @array2);
って書くと思うな 配列をコンマで区切って並べると、多次元配列にならずに配列が繋がるだけ
というシンプルな仕様が仇になってるんだよな
どうあがいても、引数に配列が現れると、その後の引数と合体してしまうので、
リファレンスで渡すしか無い
だからって、push(\@array, $var) みたい使い方を強いるのは不格好過ぎる
ということで、呼び出し側では実引数を渡しているように見えて、
裏ではリファレンスで受け取るというねじれが生じていて、
プロトタイプでそのねじれを吸収している >>893
10人中一人は
my $arr ; my @arr ;
&func($arr, @arr);
って書いて、>>882みたいに「undefだったら動かない」って
首をひねるハメになる。 通常は、プロトタイプ使ったサブルーチンはモジュールの中に隔離して
perldocだけ読ませて使わせるから、>>893の問題は生じないんだけどなw
個人のコードでどう扱うかは知らん。
代表的なプロトタイプのコードの例↓(List::MoreUtilsの古いバージョン)
https://fastapi.metacpan.org/source/ADAMK/List-MoreUtils-0.33/lib/List/MoreUtils.pm >>899
ん?
「&つけて呼び出すと、プロトタイプを無視する」って言う
古くからある悪名高い挙動が変更になったのか?
すまんが俺は古いバージョンでレスってたわ。
それだったら喜ばしい事だね。 暇だったから、plenv に 5.30.1 突っ込んで確認したが、エラーにならん
もちろんuse strict; use warnings; 効かせて
# ストロベリーとかの環境は知らん
sub pusht (¥@@){ my $c = shift ; push @{$c}, @_ ; }
my @arr ;
my $arr ;
pusht @arr, 1, 2, 3, 4 ;
&pusht( $arr, 1, 2, 3, 4 ) ;
# @arr => ( 1, 2, 3, 4 )
# $arr => undef ふつうに関数を呼び出すのにわざわざ&をつけるようなヤツは、10人に1人もいねえよ。w いないとどれだけ楽か(泣)
「KENT-webに書いてありましたよ」
「」 >>902
そのレスは>>899がレスる前に欲しかったなw
無駄な作業しなくて済んだし、恥もかかずに済んだw &つけるのって少数派なのか
俺絶対つけてるけど
ある現場で「え、今そんなのつけませんよ…」ってちょっと引いてすらいる感じで言われたことある
まあもうその現場もrailsになったはずだけど Perl5で&を使うのは、関数リファレンスを解決するときだけやろ。
>>903
Perl4レベルの遺跡やな。
もう昔々のことだから、忘れてやれ。。。 これは関数であるって目印としてつけてる
俺の中では可読性の為
つけないのはData::Dumper()とかモジュールから直で呼ぶ場合だけかな 呼出で挙動がかわるの、充分に分ってるなら「個人で使うなら」いいんじゃねーの? プロトタイプの呼出以外にも
@_ = (1,2,3,4) ; &func ;
で特殊挙動するし、地雷だらけだよXXルーチン
なんでXXがNGワードになってんの?
北島三郎のことXXちゃんって書き込めないの?
俺の環境だけ?
>>907
「perl, XXルーチン」でググると検索上位に来るんだよ、今でも teratailのサブルーチン絡みの質問斜め見て、頭痛くなったわ。
質問者はしょうがないとしても、回答で&付けるってどういう了見だ? >>904
お作法本全盛期(2010年代前半)なら、相手はお作法本を読んでる可能性がある。
引いてる程度じゃなくて、どん引きされたのかもよ
# お作法本: Perl ベストプラクティス、Effective Perl etc.
KENT-webもだけど、お作法本インスパイヤで、オレオレお作法のページが
山程あるのも滅んで欲しいわ。 一つじゃないのは当たり前
けど、オレオレお作法のページはいらない Perl6無くなったんだね。今更知った。
新言語「Raku」として生きていくそうな
https://ja.wikipedia.org/wiki/Raku keysがスカラを引数に取れるせいで、なんか間違った書き方してる所があちこちある
どっちでも大抵は動くけど、エラーで止まりやすい
明示的にデリファレンスしてればエラーにはならない それ、実験的に5.14から搭載されて、5.24で削除された機能
エラーで止るのは環境依存か、書き手がヘボか
そもそも使うんじゃねー、ってのが主旨なら、同意 配列があって、条件に合わないものを削りたい
0 .. $#array に対してループしながらspliceすると、
$i-- でも redo でもなんか不安がある
どうするのが定番なんだろう @array = grep { $_ > 0 } @array
とやって平気な気がしない
別の配列を用意していいなら既に出来ていて、
それを何とかすっきりできないかと (平気な気がしないとか言われても知らんがな)
まず「すっきりできる」を定義してください spliceするのはよくない気がする→何が定番なんだろうって話だと
grepが定番でしょ
別に結果配列用意するのでもいいんじゃないの spliceの、僕が考えた最強関数的な仕様はイヤかも。
もっと構文レベルで同じことができると良かった。 WindowsでPerlを使いたいんですが、どれが良いですか。
ActivePerlはアンインストールしてもゴミが残るそうなので避けたいのですが。 Windows10, WSL, Ubuntu 18.04 なら、最初から入っているけど
file `which perl`
/usr/bin/perl: ELF 64-bit LSB shared object 以下省略 Perlを勉強しています。
「use constant」で定義したハッシュのキーを
keys関数で取り出したいのですが出来ません。
どのような方法で取り出せますか?
use constant H => { a=>'AAA', b=>'BBB' };
foreach ( keys H ) #エラー。「keys %H」とするとエラーにならないが何も得られない。
{
print $_, "\n";
}
宜しくお願いします。 use constant H => { a=>'AAA', b=>'BBB' };
foreach (keys %{H()}) {
print $_, "\n";
} >>933
ぬおおおおっ…Perlムズイっす。
「H()」この部分はハッシュへの参照を返してるのだと思うのですが、
実体はサブルーチンだったのですね!「&H」でも上手く行きました。 >>933
お礼を記し忘れていました。
ありがとうございました。 Perl は難しすぎる。
Ruby では、
hash = { a: 1, b: 2 }
hash.each_key { |key| p key }
出力。:a などはシンボル
:a
:b >>936
そういう話をしているのではないです。
そのコードを見る限り、
普通のハッシュキーを取り出すだけだったらPerlの方が簡単な気がします。
my %h = ( a => 1, b => 2 );
print "$_\n" foreach ( sort keys %h );
結果:
a
b
※>>933は、「use constant」で定義したハッシュのキーの事です。 constantの実体は値を返すsubなので、%{}でデリファレンスしてね (?:)
をいつも忘れるんだが、何かいい覚え方は無いだろうか >>939
何を忘れんの?
「?」?「:」?
さすがに「()」は忘れんよな? >>939
いいじゃんべつに。気にせず普通の括弧にして捨てろ。 >>939
後で参照する ? 単に丸括弧を使う : 丸括弧内に「何か」を入れる
さて、「何か」とは、一体何だっただろうか?そうだ、三項演算子だ!
…と覚える。 >>943
「(?」でひとつとするべき。
その次に「:」「!」などが修飾子としてつく。 あと、マッチングのオプションのsとmも毎回検索してる
最初に思うのは大抵逆 (?シリーズをいろいろ使ってれば、あとは:だけだけど、
そもそも(?:しか使わないんだよな
いろいろ便利そうな拡張ではあるけどこれ以上可読性下げてどうする TABをデリミタにしてデータが1行に並んでいる
但し、""で囲まれていれば内部にTABを使ってもよい
というルールのデータに対して、""に囲まれているTABをスペースで置換したい
どう書けばいい? 多分、これでいけると思う。
while(s{(".*?)\t(.*?")}{$1 $2}){} while(<>){
while(s{(".*?)\t(.*?")}{$1 $2}){}
print;
}
これで解らないなら、「Perlの入門書をよく読みましょう」
としか言えないのだが。 while($str =~ s{(".*?)\t(.*?")}{$1 $2}){}
しかし、Perlを使うなら、文中で省略されている$_ のことは
知っておかないといけない。 タブ文字が複数あったら?とかダブルクォートが含まれてたら?とか、不安もいろいろ。
いわゆるExcelCSVなら、置換一発とはイカンやろな。
CSVモジュールでも探すか、マジメに自作するかして、セルごとに置換しないと個人的には落ち着かないな。 $_ などの特殊変数に依存したコードを書くと移植性と可読性が著しく低下する。
正規表現にまつわる特殊変数も厄介。別の正規表現が呼ばれて上書きされてしまうからすぐにコピーしないといけない。 ビットシフト演算の挙動の違いが表面化した
32bitと64bitのビルドの違いにより、1 << 32の結果が変わる
32bitのperlが2^32以上の整数を扱えない訳ではないので、
ビットシフト演算子を使わずにビットシフト演算子と同じことをやらないといけない
何か抜け道は無いもんか >>955
シフトするだけなら2倍したり2で割ってintにすれば良いのでは?
もっと大きなビットを扱いたい場合は Math::BigInt かな。 use bigint だと透過的にできることがわかった。
こんなのできたし。
$ perl -e 'use bigint; my $x = 1; $x <<= 256; print "$x\n"; if ($x & (1 << 256)){print "OK\n";}'
115792089237316195423570985008687907853269984665640564039457584007913129639936
OK
$
日本語訳された bigint のマニュアル
https://perldoc.jp/docs/modules/bignum-0.23/bigint.pod 何をしたいかというと、8byte単位の送信データがあって、
実際にはそれを64bitと見ていて、あるレコードは何bit目から何bit長、みたいに詰め込まれている
byte間とか平気でまたぐ
そういう64bitにデータをセットしたり取り出したり、という操作をしようと思うと、
1変数が64bitになっている方が楽に書ける
でも32bitの処理系だとできない ネットワークの通信データの取り出しなら unpack でフォーマットを N2 で配列または変数2個に取り出してからやれば楽なのでは? やれるとすっきりするけど、バイトオーダーやエンディアンがころころ変わるから、
何か落とし穴がありそう Perl の仕様が邪魔してるということなら Inline::C とかが役に立つかも。 pack, unpack は互換性重視していると思うが? 少なくともフォーマットの N 等は同じ4バイトだよ。
その辺どうしても信用できないなら自分専用の pack, unpack を作れば良いんじゃないかな。
そうすると pack, unpack と同じ形式である必要もないわけだが。 そういえば Perl のネイティブな整数のサイズって C のどれなのかな。
perlnumber には「perl をビルドする際に使われた C コンパイラが対応している形式」と
書かれてるけど。
ちなみに今使ってる環境では int ではなく long , long long と同じ 8 バイトのようだ。 Perl5のビルドはやった事ないので知らないが、多分デフォルトがCのintと同じで指定すれば変えられるって感じなのではないかな。
perl -V で実行するとそういう設定値が沢山出てくるよね。その中に intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
のようなものが出てくる。
そういや前に整数のバイト数でハマったことあったな。 fcntl() の F_SETLKW の時に渡す flock 構造体のバイナリで
pack('s2l3', F_WRLCK, SEEK_SET, 0, 0, 0) ってやっててうまく行ってたプログラムが別の環境に持って行って動かしたら
ロックが掛かったり掛からなかったりするようになり、良く調べてみたら pack の l は64bit環境でも 32bit 固定だが
struct flock の方は l_start, l_len が32bit OS では 4 バイト、64bit 環境では 8 バイトになっていた。
そもそも pack してバイナリにしなければいけないような引数の渡し方がいけないだけだとは思うが、結局どちらの
環境でも動くプログラムにするために pack('s2l5', F_WRLCK, SEEK_SET, 0, 0, 0, 0, 0) で誤魔化した。
やっぱこういうのは本来ならモジュール作ってそこで吸収した方が良いんだろうな。
と思ったらあった。
https://metacpan.org/pod/File::FcntlLock
是非デフォルトでこういうモジュールも perl と一緒にインストールされて欲しいものだな。 ありがとう。たまたま Perl のソースコードをダウンロードしてあるから
INSTALL を読んでみたら (いや、先に読んどけという話だが)
C コンパイラがサポートしてなくても use64bitint というオプションを使えば
整数のサイズが 64 ビットになるらしい。
Debian のパッケージでもこれを使ってるようだ。
C コンパイラの仕様は Config モジュールで得られるから
それを使って環境に合わせた処理が可能になる場合もあるが
Linux の flock 構造体はメンバの順番すら保証されてないようだから無理そう。 間違えた。「C コンパイラが」じゃなくて「CPU が」だ。
Configure を見た限りでは、8 バイト整数の型として採用する優先順位は
int, long, long long, int64_t の順で
8 バイトの型が無ければ Configure が失敗するようだ。
あっても CPU が対応してなくてライブラリで実現してるような環境だと
速度のためにあえて使わないという選択もあるかと思うが
long が 8 バイトだと強制的に使わされるようだ。
試せる環境が無いから勘違いしてるかもしれないが。 テーブルがあってインデックスで取り扱いたい
でもテーブルを作る時にカウンタとか意識したくない
配列なら
push @table, $data;
で済むけど、ハッシュにしたい
$table[$i]->data1 = $data1;
あるいは
$table->[$i]->data1 = $data1;
そんなことできたっけ 全部一度に判ってるなら、無名ハッシュをpushすればいいんだけど
ちょびちょび追加していきたい 親の方は無限ループにしておいて、適宜forkしてメインの処理をさせる
終わったら子はexitする
という作りで基本的にうまくいってるのに、たまに親が子だと思ってexitしとる
$pid = fork;
if (!$pid) {
exec($command);
exit;
}
この書き方に何か問題が? 親プロセスがwait $pid しないとゾンビが蓄積される。
それが続くと0ではなくundefを返すと思う。思うとしか言えないのはperldocに書かれてないから。
defined $pid でundefと0を区別する必要あり。
$!にResource temporarily unavailableのようなエラーが渡されるのでたぶんそう。
なのでちゃんと親プロセスがwait $pidすれば回避できる。 訂正。
perldoc -f forkにfork失敗時にundefを返すことが書かれてたわ やっぱり失敗してるんだよな
リトライするように直して試してみてるとこ
どういう理由で失敗するんだ?
activeperl windows版のforkもどきだからじゃないの? 今たまたま何かのリソースが全部埋まってて、一瞬待ってくれたら準備できるよ
なんだったら、リトライは隠蔽してくれて良さそうなもんなのに
IO関係はみんなそうなってる Perlはかなりの低レイヤーでも使われることがあるからな。
そんな冗長にはできんやろ。
そもそも、ぜんぜんwaitpid()しなかったらいずれ困るんだから、早くエラーになったほうがまし。 activeperlで
forkで返るpidがマイナスの値なんだけど、
Win32::Process::List で GetProcesses して得られるものとは別物なの? 疑似プロセスIDは、OSのプロセスIDとは別物なのか
要は、forkで分岐したプロセスがまだ生きてるかどうか親から周期的に監視したいんだけど
waitすると親が止まってしまうのでどうしたもんか perlのスレッドは標準IOやパイプの取り扱いが難しい、というか動きが怪しい シェルスクリプトではkill -0 PIDでプロセスが生きてるか調べられる!
そういう用途にはシェルスクリプトを使うべき! GetProcessesでpython.exeを見つければだいたい目的は達成するんだけど、
他に使ってる人がいると間違う 実行バイナリやシェルコマンドをP言語スクリプトから呼び出すソリューションが最も汎用性が高い
古事記にもそう書いてある そこもちゃんとユーチューバーのKANTのサロンで言ってる!って
語尾に付けないと このスレ、消費に9年以上かかってるとか盛者必衰の理をあらわしてて草 9年か・・・。Perlもずいぶんと長生きだね。
次スレ
【古典的モダン】Perlについての質問箱 51箱目
https://mevius.5ch.net/test/read.cgi/tech/1621994129/ このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 3413日 0時間 39分 17秒 5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。
▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/
▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php レス数が1000を超えています。これ以上書き込みはできません。