2

私はこのコードを持っています:

#!/usr/bin/perl

package Modules::TextStuff;  

use strict;  
use warnings;  
use Exporter;  
our @ISA = qw(Exporter);  
our @EXPORT = qw(get_text);  

my $author;  

my $text_tmp1 =<<'ENG';  
This is a template text  
by $author.   
ENG


sub get_text {  
        my $tmp = shift @_;  
        $author = shift @_;  
        print "In sub author= $author lang = $tmp \n";  
        my $final_str = eval('$text_'.$tmp);  
        print "$final_str \n";  
        return $final_str;  
}  
1;  

テスト スクリプト:

#!/usr/bin/perl  

use strict;  
use warnings;  

use Modules::TextStuff;  

my $str = get_text('tmp1','jim');  
print $str;  

テスト スクリプトを実行すると、機能しません。私は得る:

サブ著者で=ジム・ラング= eng

変数 "$text_tmp1" は (eval 1) 行 2 で使用できません。連結 (.) または文字列での初期化されていない値 $final_str の使用

どうすればこれを修正できますか?

4

3 に答える 3

0

私はいくつかのことを見ています:

  • まず$text_tmp1、パッケージ変数ではありません。で宣言したため、レキシカルスコープですmy。パッケージ変数として必要で、すべてのサブルーチンまたはサブルーチンで表示する必要がある場合は、 で宣言する必要がありますour
  • モジュールが記述どおりにコンパイルされません。をソースにしようとしていますが$author、定義されていません。
  • あなたは何をしていevalますか?これは非常に多くのレベルで間違っています。

これが私がそれを行う方法です:

#! /usr/bin/env perl

package Modules::TextStuff;  

use strict;  
use warnings;  
use Exporter qw(import);
use Carp;
our @EXPORT_OK = qw(get_text);

our %templates;                # This is now a package variable

#
# TEMPLATES
#

$templates{tmp1}=<<TEMPLATE;   # We'll use `%s` for replacements
This is a template text  
by %s.
TEMPLATE

$templates{tmp2}=<<TEMPLATE;
This is another template and we will substitute 
in %s in this one too.
TEMPLATE

sub get_text {  
    my $template = shift;  
    my $author   = shift;
    if ( not exists $templates{$template} ) {
        croak qq(Invalid template name "$template");
    }
    return sprintf $templates{$template}, $author;
}
1;

これらの各テンプレートを%templatesハッシュのエントリにします。evalテンプレートの変数名を計算する必要はありません。また、 existsを使用して、ユーザーが有効なテンプレートを渡したかどうかを実際にテストできるようになったことにも注目してください。

また、 with and not%templateで宣言されていることに注意してください。これにより、パッケージ内のサブルーチンを含むパッケージ全体で使用できるようになります。ourmy

@EXPORT_OKの代わりにも使用し@EXPORTます。より礼儀正しいとされています。ユーザーの名前空間を汚染する許可を求めています。それは、誰かのドアをノックして、ビールを求めて冷蔵庫の中をかき回しているのではなく、ビールを飲むことができるかどうか尋ねるようなものです.

sprintfを使用して置換可能なパラメーターを処理する方法に注意してください。これにより、eval の必要がなくなります。

Perlbrew#! /usr/bin/env perlなどとの互換性が高いため、プログラムヘッダーでも使用することを好みます。ユーザーのパスにある実行可能な Perl プログラムを見つけるために使用しています。このように、それが、、、または/usr/bin/env/bin/perl/usr/bin/perl/usr/local/bin/perl$HOME/perl5/perlbrew/perls/perl-5.18.0/bin/perl

モジュールを使用するには、次のようにします。

#! /usr/bin/env perl

use strict;
use warnings;
use feature qw(say);

use Modules::TextStuff qw(get_text);

say get_text('tmp1','jim');

あなたがかけた電話とほとんど同じです。これは出力します:

This is a template text  
by jim.
于 2013-09-18T03:38:44.683 に答える