2010-04-12 12 views
16

मुझे कुछ मॉड्यूल परिभाषित करने और एक ही फाइल में उन सभी का उपयोग करने की आवश्यकता है। नहीं, मैं आवश्यकता को बदल नहीं सकता।मैं एक पर्ल पैकेज को कैसे कॉल कर सकता हूं जिसे मैं उसी फ़ाइल में परिभाषित करता हूं?

मैं निम्नलिखित की तरह कुछ करना चाहते हैं:

{ 
    package FooObj; 

    sub new { ... } 

    sub add_data { ... } 
} 

{ 
    package BarObj; 

    use FooObj; 

    sub new { 
     ... 
     # BarObj "has a" FooObj 
     my $self = (myFoo => FooObj->new()); 
     ... 
    } 

    sub some_method { ... } 
} 

my $bar = BarObj->new(); 

हालांकि, इस संदेश में परिणाम:

@INC में FooObj.pm पता नहीं लगा सकता ...
BEGIN विफल ...

मैं इसे काम करने के लिए कैसे प्राप्त करूं?

+3

संकेत यहां त्रुटि में है: "FooObj.pm का पता नहीं लगा सकता"। .pm हमेशा एक फ़ाइल का मतलब है। –

उत्तर

23

use छोड़ें। गंभीरता से।

use किसी अन्य फ़ाइल से कोड में पढ़ने के लिए perl बताता है, जिसे आपको करने की आवश्यकता नहीं है क्योंकि कोड एक ही फ़ाइल में है।

+0

और 'उपयोग' के उपयोग के बिना 'निर्यातक' द्वारा निर्यात किए गए कुछ भी आयात कैसे करें? – ceving

+0

@ceving कॉल 'आयात' सीधे। जैसे, 'FooObj-> आयात (@params)' इस सवाल के कोड के मामले में (अगर यह 'इस्तेमाल किया Exporter')। –

+0

नहीं मेरे मन में एक अलग प्रश्न था: http://stackoverflow.com/q/33634898/402322 – ceving

14

जब तक कि मैं एक निजी पैकेज बनाने की कोशिश नहीं कर रहा हूं जिसे किसी को भी पता नहीं होना चाहिए, मैंने प्रति फ़ाइल एक पैकेज रखा है। यह समस्या हल करता है। लेकिन, चलिए उन्हें एक ही फाइल में डाल दें।

use एक फ़ाइल लोड करता है और उस पैकेज में import विधि को कॉल करता है। यह वास्तव में केवल आकस्मिक रूप से है कि इसका तर्क मॉड्यूल नाम की तरह दिखता है। यह फाइल की तलाश में है। अगर फ़ाइल नहीं है, तो यह बारफ है।

आप ऐसा कर सकते हैं, जहां BarObj मानता है कि FooObj पहले से ही वहाँ है:

{ 
    package FooObj; 
    sub new  { bless { _count => 0 }, $_[0] } 
    sub add_data { $_[0]->{_count}++ } 
} 

{ 
    package BarObj; 
    use Data::Dumper; 

    sub new { 
     bless { myFoo => FooObj->new }, $_[0]; 
     } 

    sub foo   { $_[0]->{myFoo} } 
    sub some_method { print Dumper($_[0]) } 
} 

my $bar = BarObj->new; 
$bar->some_method; 

आप एक पैकेज के साथ बातचीत करने की जरूरत है (और है कि सभी यह है: नहीं एक मॉड्यूल या किसी वस्तु), तुम बस इसे उपयोग करने से पहले इसे परिभाषित करने की आवश्यकता है। आप कुछ आयात करने की आवश्यकता है, तो आप कॉल कर सकते हैं import सीधे:

FooObj->import(...); 

वहाँ FooObj से कुछ है कि आप आयात करना (लेकिन वारिस नहीं!) चाहते हैं, तो आप कोई लोड हो रहा है के साथ सीधे import फोन है मान लीजिए;

{ 
    package FooObj; 
    use Data::Dumper; 
    sub new  { bless { _count => 0 }, $_[0] } 
    sub add_data { $_[0]->{_count}++ } 

    use Exporter qw(import); 
    our @EXPORT = qw(dumper); 
    sub dumper { print Dumper($_[0]) } 
} 

{ 
    package BarObj; 
    FooObj->import; 

    sub new { 
     bless { myFoo => FooObj->new }, $_[0]; 
     } 

    sub foo   { $_[0]->{myFoo} } 

    # dumper mixin, not inherited. 
    sub some_method { dumper($_[0]) } 
} 

my $bar = BarObj->new; 
$bar->some_method; 
10

सम्मेलन द्वारा हम एक पैकेज में एक पैकेज डालते हैं और उन्हें एक ही चीज़ कहते हैं, लेकिन यह केवल सुविधा के लिए है। आप एक ही फाइल में एकाधिक पैकेज डाल सकते हैं। चूंकि वे पहले ही लोड हो चुके हैं, इसलिए आपको use का उपयोग करने की आवश्यकता नहीं है।

आपको पैकेज के लिए विशेष स्कोपिंग बनाने की भी आवश्यकता नहीं है, क्योंकि पैकेज कीवर्ड इसका ख्याल रखता है। ब्रेसिज़ का उपयोग our चर के स्कॉइंग के साथ मदद करता है। तो आपको उन ब्रेस ब्लॉक की कड़ाई से आवश्यकता नहीं है, लेकिन वे एक अच्छा विचार हैं।

use उचित फ़ाइल लोड करने के लिए पैकेज नामकरण सम्मेलन का उपयोग करता है। मॉड्यूल के अंदर package कीवर्ड नामस्थान को परिभाषित करता है। और आयात कार्य पैकेज लोडिंग को नियंत्रित करते हैं (आमतौर पर निर्यातक से विरासत में प्राप्त)।

#!/usr/bin/perl 

use strict; 
use warnings; 

package FooObj; 

sub new 
{ 
     my $this = shift; 
     my $class = ref($this) || $this; 
     my $self = {}; 
     bless $self, $class; 
     $self->initialize(); 
     return $self; 
} 

sub initialize { } 
sub add_data { } 

package BarObj; 

#use FooObj; <-- not needed. 

sub new 
{ 
     my $this = shift; 
     my $class = ref($this) || $this; 
     my $self = { myFoo => FooObj->new() }; 
     bless $self, $class; 
     $self->initialize(); 
     return $self; 
} 
sub initialize { } 
sub some_method { } 
sub myFoo  { return $_[0]->{myFoo} } 

package main; 
use Test::More; 
my $bar = BarObj->new(); 
isa_ok($bar,  'BarObj', "bar is a BarObj"); 
isa_ok($bar->myFoo, 'FooObj', "bar->myFoo is a FooObj"); 
done_testing(); 

__DATA__ 

ok 1 - bar is a BarObj isa BarObj 
ok 2 - bar->myFoo is a FooObj isa FooObj 
1..2 
+2

+1 दिलचस्प जानकारी के लिए, तथापि मैं अभी भी ब्रेसिज़ का उपयोग करना पसंद के रूप में मुझे लगता है कि यह दृश्य स्पष्टता कहते हैं। –

+0

रॉबर्ट, मैं आपका बिंदु देखता हूं। मैं अक्सर (नाम) दृश्य स्पष्टता के लिए नंगे ब्रेसेस का उपयोग करें - आम तौर पर सिर्फ इससे पहले कि मैं तय करते हैं कि किसी दिए गए खंड का अपना दिनचर्या में या कि एक ड्राइवर स्क्रिप्ट और अधिक कार्यक्षमता वापस मॉड्यूल को स्थानांतरित करने के लिए की जरूरत है पुनर्संशोधित की जरूरत है। मैं नहीं अक्सर एक एकल फाइल में कई संकुल रखूँ, तो वास्तव में संभालो या नहीं करने को संभालो करने की आवश्यकता पर विचार नहीं किया है। – spazm

+6

यह केवल स्पष्टता नहीं है, लेकिन यह एक scoping मुद्दा है। पैकेज एक गुंजाइश नहीं बनाते हैं, ताकि मेरे() वेरिएबल में आपके पास ब्रेसिज़ के बिना फ़ाइल स्कॉप्ड हो जो अन्यथा इसे सीमित कर दे। –

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

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