2010-10-22 7 views
16

मुझे कुछ विशेषताओं (शायद इस संदर्भ में गलत शब्द) निजी होना चाहिए, यानी, ऑब्जेक्ट उपयोग के लिए केवल आंतरिक - बाहर से पढ़ा या लिखा नहीं जा सकता है।मैं आंतरिक (निजी) मूस ऑब्जेक्ट चर (गुण) कैसे बना सकता हूं?

उदाहरण के लिए, कुछ आंतरिक चर के बारे में सोचें जो कि किसी भी प्रकार के तरीकों को सेट करने की संख्या की गणना करता है।

मुझे इस तरह के चर को कहां परिभाषित किया जाना चाहिए?

उत्तर

13

Moose::Manual::Attributes निजी विशेषताएं बनानी निम्नलिखित तरीके से पता चलता है:

has '_genetic_code' => (
    is  => 'ro', 
    lazy  => 1, 
    builder => '_build_genetic_code', 
    init_arg => undef, 
); 

स्थापना init_arg इस विशेषता निर्माता पर सेट नहीं किया जा सकता है। इसे rw बनाएं या writer जोड़ें यदि आपको इसे अपडेट करना है।

/I3az/

+3

सवाल पढ़ने के साथ-साथ लेखन के बारे में पूछता है। जहां तक ​​मैं कह सकता हूं, मूस (2.0401) के जनवरी 2012 संस्करण में, इस तरह से किए गए गुण अभी भी ऑब्जेक्ट के बाहर से पठनीय हैं। उदाहरण के लिए, 'मेरा $ एम = मूसऑब्जेक्ट-> नया(); $ m प्रिंट करें -> _ genetic_code; 'विशेषता में जो कुछ भी संग्रहीत है प्रिंट करेगा। मुझे नहीं पता कि उसके आस-पास कोई रास्ता है या नहीं। यह मुझे कभी परेशान नहीं करता है, लेकिन मुझे लगता है कि यह उल्लेखनीय है। –

+0

@ एलनडब्ल्यू। स्मिथ बदल रहा है 'is =>' ro'' 'is =>' bare'' मदद 'है? उस स्थिति में, बाहर से '_genetic_code' तक पहुंचने का एकमात्र तरीका मूस के नीचे ही दिखना होगा और ऑब्जेक्ट हैश या कुछ देखें, क्योंकि मूस रीड एक्सेसर भी नहीं बनायेगा। क्या वो सही है? – sundar

10

आप कुछ इस तरह की कोशिश कर सकते हैं:

has 'call_counter' => (
    is  => 'ro', 
    writer => '_set_call_counter', 
); 

is => 'ro' विशेषता केवल पढ़ बनाता है। मूस एक गेटटर उत्पन्न करता है। आपका तरीकों मूल्य बढ़ाने, इसलिए जैसे के लिए गेटर का उपयोग करेगा:

sub called { 
    my $self = shift; 
    $self->_set_call_counter($self->call_counter + 1); 
    ... 
} 

writer => '_set_call_counter'_set_call_counter नाम के एक सेटर उत्पन्न करता है। मूस सच निजी विशेषताओं का समर्थन नहीं करता है। बाहरी कोड, तकनीकी रूप से, _set_call_counter पर कॉल कर सकते हैं। सम्मेलन के अनुसार, हालांकि, एप्लिकेशन अंडरस्कोर से शुरू होने वाली विधियों को कॉल नहीं करते हैं।

+2

गोपनीयता डेटा छिपाने के बारे में है, डेटा सुरक्षा नहीं। पर्ल वास्तविक निजी विशेषताओं का समर्थन नहीं करता है क्योंकि आप सीधे विशेषताओं तक पहुंच सकते हैं। मैं बस यह इंगित करना चाहता था कि अगर आप उन्हें अप्रत्यक्ष रूप से एक्सेस कर सकते हैं तो यह एक और कहानी होगी ... – wprl

+3

* मूस * मूल रूप से निजी विशेषताओं का समर्थन नहीं करता है। पर्ल उदाहरण के लिए बहुत कम प्राकृतिक रूप से बंद कर सकते हैं उदाहरण के लिए कम से कम प्राकृतिक बंद आधारित उदाहरण प्रकार। उन्हें काम करने के लिए आपको जो हुप्स कूदना है, वे अधिकांश उपयोग मामलों के प्रयास के लायक नहीं हैं। पेडेंट्री क्षमा करें। – perigrin

2

मैं मूस पूरी तरह से निजी जिम्मेदार बताते हैं बनाने के लिए एक तरह से यह पता लगाने के लिए सक्षम नहीं किया गया। जब भी मैं एक विशेषता बनाने के लिए has 'name' => (...); का उपयोग करता हूं, तो यह हमेशा कम से कम पढ़ने के लिए खुला रहता है। वस्तुओं के लिए मैं वास्तव में निजी होना चाहता हूं, मैं मूस पैकेज के अंदर मानक "मेरे" चर का उपयोग कर रहा हूं। एक त्वरित उदाहरण के लिए, निम्नलिखित मॉड्यूल "CountingObject.pm" लें।

package CountingObject; 

use Moose; 

my $cntr = 0; 

sub add_one { $cntr++; } 

sub get_count { return $cntr; } 

1; 

उस मॉड्यूल का उपयोग करने वाली स्क्रिप्ट्स में $ cntr चर के लिए कोई सीधी पहुंच नहीं है। उन्हें "add_one" और "get_count" विधियों का उपयोग करना चाहिए जो बाहरी दुनिया के लिए एक इंटरफ़ेस के रूप में कार्य करते हैं। उदाहरण के लिए:

#!/usr/bin/perl 

### Call and create 
use CountingObject; 
my $co = CountingObject->new(); 

### This works: prints 0 
printf("%s\n", $co->get_count()); 

### This works to update $cntr through the method 
for (1..10) { $co->add_one(); } 

### This works: prints 10 
printf("%s\n", $co->get_count()); 

### Direct access won't work. These would fail: 
# say $cntr; 
# say $co->cntr; 

मैं मूस के लिए नया हूँ, लेकिन जहाँ तक मैं बता सकता हूँ, इस दृष्टिकोण पूरी तरह से निजी चर प्रदान करता है।

+3

सावधान रहें कि "मेरे" चर आपके सभी ऑब्जेक्ट उदाहरणों के बीच साझा किए जाते हैं क्योंकि वे पैकेज का हिस्सा हैं, और ऑब्जेक्ट का प्रतिनिधित्व करने वाले धन्य हैश का हिस्सा नहीं हैं। यह आमतौर पर आप नहीं चाहते हैं। –

6

मुझे लगता है कि आप MooseX::Privacy चाहते हैं।

perldoc आपको बताता है कि आप सभी की जरूरत चाहिए - यह आप के रूप में उन्हें घोषित करने के लिए अनुमति देता है अपनी विशेषताओं के लिए एक नया विशेषता कहते निजी या संरक्षित:

has config => (
    is  => 'rw', 
    isa => 'Some::Config', 
    traits => [qw/Private/], 
); 
3

एलन डब्ल्यू स्मिथ एक शाब्दिक के साथ एक निजी वर्ग चर प्रदान की परिवर्तनीय, लेकिन यह कक्षा में सभी वस्तुओं द्वारा साझा किया जाता है।हालांकि अगर आप नहीं, तो आप एक चाल के अंदर से बाहर वस्तु शिविर से उधार ले सकते हैं कर सकते हैं गोपनीयता एक अच्छा जवाब है,:

my $c1 = CountingObject->new(); 
printf("%s\n", $c1->get_count()); 
# also shows a count of 10, same as $co 

MooseX का उपयोग करना: उदाहरण स्क्रिप्ट के अंत में एक नई वस्तु जोड़ने का प्रयास करें

package CountingObject; 

use Moose; 

my %cntr; 

sub BUILD { my $self = shift; $cntr{$self} = 0 } 

sub add_one { my $self = shift; $cntr{$self}++; } 

sub get_count { my $self = shift; return $cntr{$self}; } 

1; 

इसके साथ, प्रत्येक ऑब्जेक्ट का काउंटर एक शब्दावली हैश में प्रवेश के रूप में संग्रहीत किया जाता है। उपरोक्त को थोड़ा और अधिक लागू किया जा सकता है:

package CountingObject; 

use Moose; 

my %cntr; 

sub add_one { $cntr{$_[0]}++ } 

sub get_count { return $cntr{$_[0]}||0 } 

1; 
संबंधित मुद्दे