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.3
- 回答日時:
なるほど・・821からですか.
#そろそろ5.10にうつろうかな・・・Pugsでもいいんだけど(笑)
>現象の発生するサンプルは今、もうちょっと簡略化できないか
一応,シンプルにするためにソフトリファレンスを
ディスパッチテーブル(ハッシュ)にしたりする方法を
書いたのですが。。。
あとはサブルーチン,regex・・・これは本当に必要なのかな
それから,ややこしい正規表現を書くときには
xオプションも考えるべきでしょうね.
参照:Perlベストプラクティス(D.Conway,オライリー)
この回答への補足
> あとはサブルーチン,regex・・・これは本当に必要なのかな
> それから,ややこしい正規表現を書くときには
> xオプションも考えるべきでしょうね.
そうですね。
正規表現って結構難しいので行き当たりばったりでいろいろ試して
結果的に意図したとおりに動作する(していると思われる)ものを
採用しただけですので無駄があったりおかしな事やっている可能性が
高いです。
xオプションの使い方がよく分からないのですけど、余裕があったら
調べてみたいと思います。
具体的には '__([A-Z_\d]+?(\[\d+?\])?)__' か '&{(.+?)}&' に
マッチする行を変換しているのですがその際に、1行内で複数回マッチ
する場合があり、そして変換結果が空白文字列(\s)だけだったら
その行を削除してしまいたいんです。
(ただし、パターンが含まれていない行はそのままにしたいので一度、
パターンが含まれている行を取得してその行を変換した結果から判断
しています)
あと、前回の質問の補足にも書いたのですがどうやら、 regex の
正規表現の部分の直前に
if($$str =~ /$pattern/s)
のような正規表現のマッチを加えるとなぜかエラーにならなくなります。
現状ではこれで何とか回避しているのですけど、かなり不安があり
ます。
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のどちらかで修正されていることはまあ、間違いないと思います。
ただ、直接それに関する問題なのか他の問題が影響していてそれを
修正した時に関連して結果的に修正されたのかは分かりません。
お探しの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ランキング
-
Perl 強制終了の回避について
-
ArduinoのジャイロモジュールMP...
-
Excel VBAでリンク切れをチェッ...
-
例外処理のフローチャートの記...
-
エクセルVBAでシートモジュール...
-
ユーザー定義関数に#NAME?が返...
-
VBAで別モジュールへの変数の受...
-
Perlソースコードをコンパイル...
-
モジュールとは何ですか
-
Form間の値の渡し方
-
XML::Parser::Expat が無い?
-
標準モジュールを削除したい。(...
-
偶数/奇数の判定
-
perlをバージョンアップしたら...
-
MS-Access と接続する方法を教...
-
VBSがコンパイルエラーになりま...
-
AIX6でファイルのタイムスタン...
-
モジュールの最大数はいくつな...
-
VBA モジュールで共通に使う変...
-
Excel VBAで、ユーザーフォー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VHDLについてですが何がお...
-
Perl/TkのWWW::MechanizeのGET...
-
LWP::Simpleでのgetについて
-
Perl/TkでURLを既定のブラウザ...
-
LWPでHTMLが取得できないことが...
-
XML::XPathを使う
-
URI.pmの使い方を教えてくださ...
-
Perlでgoogle newsのRSSを取得...
-
mechanizeのタイムアウト処理に...
-
例外処理のフローチャートの記...
-
Excel VBAでリンク切れをチェッ...
-
ユーザー定義関数に#NAME?が返...
-
VBAで別モジュールへの変数の受...
-
"JScript"が見つかりません!
-
VBSがコンパイルエラーになりま...
-
VBでグローバル変数を宣言するには
-
エクセルVBAでシートモジュール...
-
「デバイスは PRN を初期化でき...
-
VBA This Workbookモジュール...
-
モジュールの最大数はいくつな...
おすすめ情報