簡體   English   中英

如何在Perl對象上組織私有方法?

[英]How to organize private methods on Perl objects?

處理用戶不會調用的方法的正確方法是什么? 例如,如果用戶調用方法,例如從驅動程序腳本中調用do_stuff() ,並且do_stuff()依賴於其他子例程,那么最好從do_stuff()方法中調用這些subs,如下所示:

sub do_stuff {
    my ( $self, %arg ) = @_;
    #does it things
    #and then calls the private sub as follows
    _private_sub( $self, %arg );
}

據我所知,沒有“正確”的方式。 Perl不提供隱藏功能的能力,至少我曾遇到過這種功能。 我所做的是使用命名標准,我用一個下划線啟動僅內部函數名稱,並清楚地記錄它們永遠不會被外部調用者調用。

編輯:其他答案引發了一個想法。 在每個私有方法中,您可以檢查“caller()”函數的結果,如果調用者是本地模塊以外的任何人,則中止。 老實說,我個人不會遇到麻煩,但如果由於某種原因它對你來說真的很重要,那就會強調這些方法的私人性質。

如果你的do_stuff方法需要你決定應該保持“私有”的功能,那么一定要在其中調用_private_sub 這正是它的目的。 當然,將子“私有”是一個慣例問題,因為它無法執行。

我想提一下使用coderefs進行私有子的另一種方式

my $_private = sub { ... };  # must be at least predeclared

sub do_stuff {
    my ($self, %arg) = @_;
    # ...
    my $from_private = $self->$_private->(@args);    # or
    my $more_private = $_private->($self, @args);
}

語法很奇怪,但肯定會警告用戶它是一個私有方法。 這使得子類很難繼承,這要歸功於mob強調這一點。

第二次調用使用$_private作為函數而不是方法,因此我們必須在需要時傳遞對象。 這進一步警告不要使用它。 然后它也沒有經歷正常的方法查找過程(因此稍微快一點),這是一個很好的意識。

關於究竟是什么問題,我有點不確定。

如果是關於是否在代碼中使用“私有”子程序,那么實際上沒有公認的最佳實踐。 它們非常有用,但它們並非真正私密。 我自由地使用它們。

完整的答案是使用MooseMoo或其他模塊。

而不是$self->_private_sub(...) 在我看來, $obj->_method表示法總是與作用於類實例的函數一起使用,其他類型的調用總是用於其他類型的函數。

但是,如果你是偏執狂,為什么不使用一種非傳統的方式來填充你的論點,這會讓那些試圖以面向對象的方式使用私有方法的人感到困惑?

sub do_stuff {
    my ( $self, %arg ) = @_;
    ...
    _private_sub( %arg, $self );
}

sub _private_sub {
    my $self = pop;
    my %args = @_;
    ...
}

到目前為止,您收到的所有答案都表示無法完成。 但它可以 - 在Perl 5.18及更高版本中。 請參閱perldoc perlsub有關詞perldoc perlsub例程部分

詞法子程序

警告:詞法子程序仍處於試驗階段。 在將來的Perl版本中可能會修改或刪除該功能。

詞法子例程僅在use feature 'lexical_subs'編譯指示下可用,除非禁用“experimental :: lexical_subs”警告類別,否則它會產生警告。

從Perl 5.18開始,您可以使用mystate聲明私有子例程。 與狀態變量一樣,state關鍵字僅在use feature 'state'下可用或use 5.010或更高版本。

這些子例程僅在聲明它們的塊中可見,並且僅在聲明之后:

 no warnings "experimental::lexical_subs"; use feature 'lexical_subs'; foo(); # calls the package/global subroutine state sub foo { foo(); # also calls the package subroutine } foo(); # calls "state" sub my $ref = \\&foo; # take a reference to "state" sub my sub bar { ... } bar(); # calls "my" sub 

要從子例程本身內部使用詞法子例程,必須預先聲明它。 sub foo {...}子例程定義語法尊重任何先前的my sub; state sub; 宣言。

 my sub baz; # predeclaration sub baz { # define the "my" sub baz(); # recursive call } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM