Attempt to free unreferenced scalar とは?
http://oshiete1.goo.ne.jp/qa4237453.html
の続きです。
とりあえず、下に現状で分かる最小限の再現性があるスクリプトを
書いておきます。
print &opentmpl("body");
print &opentmpl('footer'); # これがない場合はエラーにならない
sub opentmpl {
my $fn = shift;
my $VAR = shift || {};
my $file = &{$fn}();
®ex(\$file, $VAR, '__([A-Z_\d]+?(\[\d+?\])?)__', ['$VAR->{"%s"}', '$1']);
®ex(\$file, $VAR, '&{(.+?)}&', ['%s', '$1']);
return $file;
return undef;
}
sub regex {
my $str = shift;
my $VAR = shift;
my $pattern = shift;
my $replace = shift;
$$str =~ s/((([^\n]*?)$pattern(?=.*))+(\n?))/&func($1, $VAR, $pattern, @$replace)/egs;
return;
}
sub func {
my $str = shift;
my $VAR = shift;
my $pattern = shift;
my $buf = shift;
$str =~ s/$pattern/$@ = ''; $_ = eval(sprintf($buf, map { eval($_); } @_)); $@ ? $@ : $_/egs;
if($str =~ /^\s*\n?$/s) {
return;
}
return $str;
}
sub body {
print "Content-type: text/plain; charset=shift_jis\n\n";
return <<'HTML';
&{
return &opentmpl('table', {'TEST' => 'test'});
}&
HTML
}
sub table {
return <<'HTML';
__TEST__
HTML
}
sub footer {
return <<'HTML';
test
HTML
}
調べてみた限りではActivePerl for Win32以外のPerlでも同様のよう
です。
(Linux上でも同様のようです)
5.8.8ではエラーになりますが、5.10.xではエラーにならないようです。
(同じ環境において5.8.8では再現し、5.10.0にバージョンアップすると
再現しなくなり、再度5.8.8にバージョンダウンすると再現します)
本番機の環境が5.8.8で勝手にバージョンアップなどができないため、
5.8.8で正常に動作するようにするにはどうしたらよいでしょうか。
結構、無駄も多いと思いますので全く同じ動作をしながらより効率の
いい書き方ができたらいいなと思います。
(なお、実際には使用しているけど上記では使用していない部分が
含まれていてその部分がない場合もエラーにならないようです)
No.1ベストアンサー
- 回答日時:
とりあえず,再現しません.
This is perl, v5.8.8 built for MSWin32-x86-multi-thread
(with 18 registered patches, see perl -V for more detail)
Copyright 1987-2007, Larry Wall
Binary build 822 [280952] provided by ActiveState http://www.ActiveState.com
Built Jul 31 2007 19:34:48
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
perl test.pl
Content-type: text/plain; charset=shift_jis
test
test
============
use strict;
use warnings;
してないととか,サブルーチンの呼び出しに&をつけてるとか
どういう結果が期待しているものなのか不明だったりしますが,
#5.8.10でうごくんなら,その「期待された結果」を明示すべきだと
#思うけどね
こんな感じでうごく?
そもそももっと「読めるコード」にすべき.
しばらくたって自分でこのコードのやってること読めますか?
私はまったく読めません.
use strict;
use warnings;
my %subs=(
"body" => sub {
print "Content-type: text/plain; charset=shift_jis\n\n";
return <<'HTML';
&{
return opentmpl('table', {'TEST' => 'test'});
}&
HTML
},
"table" => sub {
return <<'HTML';
__TEST-TABLE__
HTML
},
"footer" => sub {
return <<'HTML';
test-footer
HTML
},
);
print opentmpl("body");
print opentmpl('footer'); # これがない場合はエラーにならない
sub opentmpl {
my $fn = shift;
my $VAR = shift || {};
my $file = $subs{$fn}->();
regex(\$file, $VAR, '__([A-Z_\d]+?(\[\d+?\])?)__', ['$VAR->{"%s"}', '$1']);
regex(\$file, $VAR, '&{(.+?)}&', ['%s', '$1']);
return $file;
}
sub regex {
my $str = shift;
my $VAR = shift;
my $pattern = shift;
my $replace = shift;
$$str =~ s/((([^\n]*?)$pattern(?=.*))+(\n?))/func($1, $VAR, $pattern, @$replace)/egs;
return;
}
sub func {
my $str = shift;
my $VAR = shift;
my $pattern = shift;
my $buf = shift;
$str =~ s/$pattern/$@ = ''; $_ = eval(sprintf($buf, map { eval($_); } @_)); $@ ? $@ : $_/egs;
if($str =~ /^\s*\n?$/s) {
return;
}
return $str;
}
この回答への補足
どうも、すみません。
現象が再現しているActivePerlは perl -v してみたところbuild 817の
ようです。
(確認したLinuxの方のPerlはちょっと分かりません)
This is perl, v5.8.8 built for MSWin32-x86-multi-thread
(with 25 registered patches, see perl -V for more detail)
Copyright 1987-2006, Larry Wall
Binary build 817 [257965] provided by ActiveState http://www.ActiveState.com
Built Mar 20 2006 17:54:25
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
> use strict;
> use warnings;
これはしていません。
(実際のスクリプトの方では strict だけしています)
> #5.8.10でうごくんなら,その「期待された結果」を明示すべきだと
> #思うけどね
ごめんなさい。
上記のサンプルの方では
Content-type: text/plain; charset=shift_jis
test
test
のような表示が出るはずです。
> こんな感じでうごく?
やはりエラーが出ているようです。
> そもそももっと「読めるコード」にすべき.
> しばらくたって自分でこのコードのやってること読めますか?
> 私はまったく読めません.
本当にすみません。
ぼくもそう思います(いつもこれで苦労していますがこれ以上うまく
組めなくて...)。
補足の所は既に書いちゃったのでこちらに失礼します。
いろいろ、過去のバージョンなどを順にインストールして調べてみた
ところどうやら、build 822で修正された問題のようです。
(build 821がDLできないので正確に確認できていませんが820では
現象が再現し、822では再現しませんでした)
現象の発生するサンプルは今、もうちょっと簡略化できないか
いろいろやっています。
既にずいぶん経っているため、新しい回答はないと思いますので
いったん質問を閉じてから再質問しようと思います。
No.2
- 回答日時:
参考情報。
Build 821 Wednesday, Jun 24, 2007
Build 821 is based on Perl 5.8.8, but also includes all changes from the Perl 5.8 maintenance branch up to change 31223 plus additional selected changes from the Perl 5.9 development branch.
Build 821 was only distributed for HP-UX.
これから考えると、Build 820 → Build 821で加えられた修正が効いているのでは?
ただし最後の行にあるように、Build 821としてリリースされたのは
HP-UX向けだけと。
どうもありがとうございます。
821か822のどちらかで修正されていることはまあ、間違いないと思います。
ただ、直接それに関する問題なのか他の問題が影響していてそれを
修正した時に関連して結果的に修正されたのかは分かりません。
No.3
- 回答日時:
なるほど・・821からですか.
#そろそろ5.10にうつろうかな・・・Pugsでもいいんだけど(笑)
>現象の発生するサンプルは今、もうちょっと簡略化できないか
一応,シンプルにするためにソフトリファレンスを
ディスパッチテーブル(ハッシュ)にしたりする方法を
書いたのですが。。。
あとはサブルーチン,regex・・・これは本当に必要なのかな
それから,ややこしい正規表現を書くときには
xオプションも考えるべきでしょうね.
参照:Perlベストプラクティス(D.Conway,オライリー)
この回答への補足
> あとはサブルーチン,regex・・・これは本当に必要なのかな
> それから,ややこしい正規表現を書くときには
> xオプションも考えるべきでしょうね.
そうですね。
正規表現って結構難しいので行き当たりばったりでいろいろ試して
結果的に意図したとおりに動作する(していると思われる)ものを
採用しただけですので無駄があったりおかしな事やっている可能性が
高いです。
xオプションの使い方がよく分からないのですけど、余裕があったら
調べてみたいと思います。
具体的には '__([A-Z_\d]+?(\[\d+?\])?)__' か '&{(.+?)}&' に
マッチする行を変換しているのですがその際に、1行内で複数回マッチ
する場合があり、そして変換結果が空白文字列(\s)だけだったら
その行を削除してしまいたいんです。
(ただし、パターンが含まれていない行はそのままにしたいので一度、
パターンが含まれている行を取得してその行を変換した結果から判断
しています)
あと、前回の質問の補足にも書いたのですがどうやら、 regex の
正規表現の部分の直前に
if($$str =~ /$pattern/s)
のような正規表現のマッチを加えるとなぜかエラーにならなくなります。
現状ではこれで何とか回避しているのですけど、かなり不安があり
ます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/07 21:04
- オープンソース Coinmarketcap api 1 2022/05/30 15:47
- Perl perlの構文でカンマの意味が分からない 2 2022/10/30 01:53
- JavaScript ソースコードのいじる場所が分かりません。 1 2022/12/23 02:06
- その他(プログラミング・Web制作) laravel 本番環境でメールが送れません。 1 2023/02/17 17:57
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- C言語・C++・C# C言語の質問です HTMLでこのようなコードを書いたのですがそれをC言語で同じように書きたいです < 1 2022/08/11 23:38
- その他(プログラミング・Web制作) python flask から fastapiへの移行時のエラー対処 1 2023/02/05 12:26
- JavaScript 1日1回引けるJavaScriptおみくじについて 1 2022/12/12 22:28
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
アルファベットに付いて質問し...
-
Wallpaper Engineでおすすめの...
-
perl LWPでURLにアクセスした時...
-
Perlでファイルの末尾から指定...
-
テキストファイルで提出とは?
-
#!/usr/bin/perlで書きだしたCG...
-
Perlのエラーについてご教授く...
-
perlのflock関数でロックをかけ...
-
ファイルアイコンの左下に緑の□...
-
perlプログラミング 空白行削除
-
perlでリテラル値はメモリにど...
-
Perlで時間の計算
-
perlについて
-
perlのrequireの動き方について...
-
perlの構文でカンマの意味が分...
-
perlについての質問
-
perlのプログラミング 部分入れ...
-
ペプシコーラとコカ・コーラとD...
-
perlをバージョンアップしたら...
-
perlについての質問
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Perl 強制終了の回避について
-
Win32でInputBoxを実装するには?
-
VHDLについてですが何がお...
-
Perl/TkでURLを既定のブラウザ...
-
LWPでHTMLが取得できないことが...
-
Perl LWPでのIPv6エラー
-
LWP::Simpleでのgetについて
-
mechanizeのタイムアウト処理に...
-
TwitterAPI1.1でGetメソッド(...
-
Excel VBAでリンク切れをチェッ...
-
Excel VBA 定義されたプロージ...
-
例外処理のフローチャートの記...
-
ArduinoのジャイロモジュールMP...
-
ユーザー定義関数に#NAME?が返...
-
「デバイスは PRN を初期化でき...
-
VBAで別モジュールへの変数の受...
-
Excel VBA 『Call』で呼び出す...
-
エクセルVBAでシートモジュール...
-
LCD ディスプレイを Raspberry ...
-
モジュールとは何ですか
おすすめ情報