2011-09-05 33 views
2

下面是一些代碼,我與實驗的摘錄:解引用在穆斯屬性持有的在內存中的文件

has buffer  => (is => 'rw', isa => 'ScalarRef'); 
has old_stdout => (is => 'rw', isa => 'FileHandle'); 

sub capture { 
    my $self = shift; 
    my $old_stdout; 
    my $buffer; 

    open $old_stdout, '>&', STDOUT 
     or croak 'Cannot duplicate filehandle'; 

    close STDOUT; 

    open STDOUT, '>', \$buffer 
     or croak 'Cannot open filehandle'; 

    $self->old_stdout($old_stdout); 
    $self->buffer(\$buffer); 
} 

sub reset { 
    my $self = shift; 

    open STDOUT, '>&', $self->old_stdout 
     or croak 'Cannot reset STDOUT'; 
} 

在別處:

my $stdout = Capture->new(); 
print "Some output\n"; 
$stdout->reset(); 

print $stdout->buffer(); 
# SCALAR(0x#######) 

print ${$stdout->buffer()}; 
# Some output 

我試圖以欺騙設置屬性hashref直接 - 它的工作原理,但我不喜歡這樣做:

open STDOUT, '>', \$self->{buffer} 
     or croak 'Cannot open filehandle'; 

我想我缺少som這裏是根本。我應該如何將$buffer(內存中的文件)存儲爲Moose屬性,以便以後可以檢索它,而調用者不必對其進行解引用?

更新

我已經添加了around方法改性劑,其中的伎倆:

around 'buffer' => sub { 
    my $orig = shift; 
    my $self = shift; 
    return ${$self->$orig} unless @_; 
    $self->$orig(@_); 
}; 

...但它仍然感覺凌亂。有沒有更好的辦法?

回答

1

的選擇是通過前面加上下劃線,使這兩個屬性(bufferold_stdout)私下再添加簡單的方法來從外部訪問的緩衝區:

sub buffer { 
    my $self = shift; 
    return ${$self->_buffer} 
} 

這也要看你是想實現重複的Capture::Tiny或類似模塊。

+0

謝謝。不希望從你的答案中拿走任何東西,很明顯,一旦我看到它。它很清楚,簡單而有效。至於capture :: Tiny - 是的,它非常相似。這是更大的一部分,我也看過Capture :: Tiny等等。我最終可能會使用CPAN模塊,但無論哪種方式,這都是一項有價值的任務,因爲我一路上學到了一些新的東西。 – Martin

1

請勿更改buffer的含義(如同您對around所做的那樣),請創建一個新的存取器。

has buffer_ref => (
    ... 
    handles => { 
     buffer => sub { 
     my $self = shift; 
     if (@_) { 
      ${ $self->buffer_ref } = $_[0]; 
     } else { 
      return ${ $self->buffer_ref }; 
     } 
     }, 
    }, 
); 
+0

+1這是一個非常穆斯林的做法。我喜歡它,它和bvr的答案之間有着密切的聯繫,它基本上做了同樣的事情。我正在研究如何使用委託,並且您的示例幫助我們澄清了使用'handles'編寫代碼的方法。但是,我認爲bvr的解決方案更簡單,更清晰,並且不需要「元類轉換」(引自Moose docs)。 – Martin

+0

@Martin,我總是把訪問器放在'handles'中。在屬性定義的其餘部分,而不是其他屬性定義中,與其他任意子潛艇相比,在這個星球的中間位置更好。沒有「扭曲」;該子文件與文件中的其他位置相同。 – ikegami

+0

這對於保持訪問器的屬性定義是一個很好的觀點 - 我確實認爲這是一個因素。什麼使我對另一個答案產生了影響,我用鼠標試了一下,結果失敗了。我知道鼠標不是我的問題的一部分,所以對此表示歉意,但事實證明,鼠標在這裏可能會有所幫助,因爲它的啓動開銷較低。 – Martin

相關問題