2012-04-18 8 views
0

私は以下に示したようなPerlコードを継承しました。パッケージには一般的なサブルーチンが含まれており、名前空間のインポートやエクスポートは行いません。この呼び出し規約は非典型的です。リファクタリングはオプションです。ローカルサブルーチンコール時にパッケージ名を指定する危険性はありますか?

私は、現在のパッケージ内でサブルーチンを呼び出すときに明示的にパッケージ名を付けることのリスク/副作用を理解することに興味があります。前もって感謝します。

package Util; 
sub _step1 { 
    # <code> 
} 
sub _step2 { 
    # <code> 
} 
sub doWork { 
    Util::_step1(); 
    Util::_step2(); 
} 
1; 
+0

明確にするために、私は既存のプロジェクトに割り当てられていることを伝える目的で、「継承」を使用しました。 – jgrump2012

答えて

3

興味深い。私はこれがどのように相続に影響を与えるか考えている。

_step2メソッドをオーバーライドするUtilクラスの子クラスを想像してください。そのクラスがdoworkメソッドを呼び出した場合子クラス '_step1_step2メソッドを呼び出すのではなく、親クラス' _step1_step2メソッドを呼び出すことになります。

補遺

関数呼び出しは、継承を無視します。モジュールは、継承のためにUtil - > _ step1()またはパッケージ - > _ step1()のような処理をする必要があり、パッケージ検索は子クラスではなくUtilで始まり​​ます。 - Ven'Tatsu

本当に?テストするのに十分シンプルだと思われる。

私のプログラムには、Local::UtilLocal::Util::Childという2つのパッケージがあります。 Local :: Util :: Childは子クラスでLocal::Utilです。

クラスLocal::Utilは、定義された以下のコンストラクタとメソッドを持っています

  • new
  • _step1
  • _step2
  • doWorkそのクラスの新しいオブジェクトを作成します。これはUtil::_step1_step2を呼び出します接頭辞。
  • doWork2_step1_step2は、Util::というプレフィックスを付けずに呼び出します。
  • doWork3:これは、接頭辞__PACKAGE___step1_step2を呼び出します。
  • doWork4:これは、と_step2と呼ばれ、接頭辞はから取られた$classです。

クラスLocal::Util::Childは、_step2メソッドを再定義します。

は、ここでプログラムです:

#! /usr/bin/env perl 
# 
use strict; 
use warnings; 
use feature qw(say); 

# This is our basic Local::Util object manipulation 

my $util_obj = Local::Util->new; 
say q("$util_obj" is a member of the ") . ref($util_obj) . q(" class); 

print q($util_obj->_step1:); 
$util_obj->_step1; 

print q($util_obj->_step2:); 
$util_obj->_step2; 

# This is a child class object of the above 

my $uc_obj = Local::Util::Child->new; 
say q("$uc_obj" is a member of the ") . ref($uc_obj) . q(" class); 

# Calls to straight forward methods 

print q($uc_obj->_step1:); 
$uc_obj->_step1; 

print q($uc_obj->_step2:); 
$uc_obj->_step2; 

# Now calls to methods that call other methods 

say qq(\n=====\$util_obj->doWork=====); 
$util_obj->doWork; 

say qq(\n=====\$uc_obj->doWork=====); 
$uc_obj->doWork; 

say qq(\n=====\$util_obj->doWork2=====); 
$util_obj->doWork2; 

say qq(\n=====\$uc_obj->doWork2=====); 
$uc_obj->doWork2; 

say qq(\n=====\$util_obj->doWork3=====); 
$util_obj->doWork3; 

say qq(\n=====\$uc_obj->doWork3=====); 
$uc_obj->doWork3; 

say qq(\n=====\$util_obj->doWork4=====); 
$util_obj->doWork4; 

say qq(\n=====\$uc_obj->doWork4=====); 
$uc_obj->doWork4; 

################################################### 
# Package Local::Util 
# 
package Local::Util; 

sub new { 
    my $class = shift; 
    my $self = {}; 
    bless $self, $class; 
} 

sub _step1 { 
    say "I'm calling Local::Util::_step1"; 
} 

sub _step2 { 
    say "I'm calling Local::Util::_step2"; 
} 

sub doWork { 
    Local::Util::_step1(); 
    Local::Util::_step2(); 
} 

sub doWork2 { 
    _step1(); 
    _step2(); 
} 

sub doWork3 { 
    __PACKAGE__->_step1(); 
    __PACKAGE__->_step2(); 
} 

sub doWork4 { 
    my $self = shift; 
    my $class = ref $self; 

    $class->_step1(); 
    $class->_step2(); 
} 
# 
############################################# 

############################################# 
# Package Local::Util::Child 
# 

package Local::Util::Child; 
use base qw(Local::Util); 

sub _step2 { 
    say "I'm calling Local::Util::Child::_step2"; 
} 

そして、ここでの出力です:興味深い

"$util_obj" is a member of the "Local::Util" class 
$util_obj->_step1: I'm calling Local::Util::_step1 
$util_obj->_step2: I'm calling Local::Util::_step2 
"$uc_obj" is a member of the "Local::Util::Child" class 
$uc_obj->_step1: I'm calling Local::Util::_step1 
$uc_obj->_step2: I'm calling Local::Util::Child::_step2 

=====$util_obj->doWork===== 
I'm calling Local::Util::_step1 
I'm calling Local::Util::_step2 

=====$uc_obj->doWork===== 
I'm calling Local::Util::_step1 
I'm calling Local::Util::_step2 

=====$util_obj->doWork2===== 
I'm calling Local::Util::_step1 
I'm calling Local::Util::_step2 

=====$uc_obj->doWork2===== 
I'm calling Local::Util::_step1 
I'm calling Local::Util::_step2 

=====$util_obj->doWork3===== 
I'm calling Local::Util::_step1 
I'm calling Local::Util::_step2 

=====$uc_obj->doWork3===== 
I'm calling Local::Util::_step1 
I'm calling Local::Util::_step2 

=====$util_obj->doWork4===== 
I'm calling Local::Util::_step1 
I'm calling Local::Util::_step2 

=====$uc_obj->doWork4===== 
I'm calling Local::Util::_step1 
I'm calling Local::Util::Child::_step2 

。私がUtil::プレフィックスを付けるかどうかにかかわらず、それは何の違いもなく、子メソッドではなく親メソッドを呼び出すのは間違いありません。 __PACKAGE__接頭辞を置くことは同じです(私はあなたが現在のクラスの定義を呼び出すことを確実にするためにそれをやっていると思いました)。私が子供に働かせる唯一の方法は、refコマンドから取得しなければならない接頭辞$classを使用することです。

他のメソッドでメソッドを呼び出すと、デフォルトでそのクラスのメソッドであり、子のメソッドではありません。私はこれが理にかなっていると思う - 特に_step1_step2のように見えるので、親メソッドの外でアクセスすべきではないプライベートメソッドです。

+0

関数呼び出しは継承を無視します。モジュールは継承のために 'Util - > _ step1()'や '__package __-> _ step1()'のような処理をする必要があり、パッケージ検索は子クラスではなく 'Util'で始まります。 –

+0

'$ self-> Util :: _ step1()'は、オーバーライドを無視するメソッド呼び出しです(基本クラスから引き続き継承します)。 – ikegami

+0

@ Ven'Tatsu上記の補遺を参照してください。あなたは、継承が別のメソッドによって呼び出されたメソッドに影響を与えないように見えるのは間違いありません。 –

0

これは問題ありません。唯一の欠点は、モジュールの名前を変更した場合、サブ呼び出しの名前を忘れる可能性があることです。

しかし、それは奇妙なことです。あなたがこれをしたい理由を教えてくれれば、もっと良い方法を提供することができます。

関連する問題