2013-07-29 8 views
6

मैं क्या अगर मैं तरीकों a और b साथ एक मॉड्यूल है और उन्हें निर्यात करना चाहते हैं:पर्ल में @ISA क्या है?

use Exporter; 
our @ISA = qw (Exporter); 
our @EXPORT = qw (a b); 

क्या मुझे समझ नहीं आता क्या इस लाइन करता है:
our @ISA = qw (Exporter); करते हैं?

+1

'perldoc perlobj' और 'perldoc perltoot' देखें। –

+2

निर्यात विधियों को समझने का कोई मतलब नहीं है?! क्या आपका मतलब "subs" है? – ikegami

उत्तर

3

@ISA पैकेज चर का उपयोग कक्षाओं के बीच विरासत निर्दिष्ट करने के लिए किया जाता है। आप इस चर को अपने आप में हेरफेर करने के लिए निराश हैं। यदि आप किसी अन्य वर्ग से प्राप्त करना चाहते हैं, तो

use parent 'Parent::Class'; 

या पूर्व v10.1 कार्य करें: इस विशिष्ट मामले में

use base 'Parent::Class'; 

, Exporter से इनहेरिट import विधि उपलब्ध कराता है। आपका कोड फिर से लिखा जा सकता है।

use parent 'Exporter'; 
our @EXPORT = qw/a b/; 

import विधि कहा जाता है स्वचालित रूप से जब अपने मॉड्यूल use घ है, और पैकेज का उपयोग करने के लिए प्रतीकों का निर्यात कर सकते हैं।


क्यों @ISA का उपयोग कर मैन्युअल रूप से खराब है:

  • @ISA को निर्दिष्ट न करें: अन्य मॉड्यूल पहले से ही यह करने के लिए प्रविष्टियों को शामिल किया है हो सकता है; यह उन्हें ओवरराइट करेगा। इसलिए, push @ISA, "Some::Class"

  • रनटाइम के दौरान @ISA संशोधित करने से बचें। जितनी जल्दी हो सके विरासत संबंध निर्दिष्ट करना बेहतर है (पार्सिंग या प्रारंभिक संकलन के बाद), ताकि आपके मॉड्यूल को प्रतिबंधों के बिना इस्तेमाल किया जा सके। आप के माध्यम से parent इतना आसान बना देता है एक BEGIN या CHECK ब्लॉक में लपेट कर सकता है, जैसे

    BEGIN { 
        push @ISA, "Some::Class"; 
    } 
    

विरासत। parent अनुरोधित मॉड्यूल को संकलित भी करेगा यदि यह पहले से लोड नहीं हुआ है: use Some::Class की आवश्यकता नहीं है।

+0

लेकिन मुझे इसे स्पष्ट रूप से लिखने की आवश्यकता क्यों है? उसके बाद मैं इसका उपयोग नहीं करता – Jim

+0

@ जिम मैं समझ में नहीं आता। निर्यातक मॉड्यूल आपको 'उपयोग' होने पर अपने पैकेज से प्रतीकों को निर्यात करने की अनुमति देता है। यह 'आयात' विधि के साथ लागू किया गया है। आप या तो खुद को लिख सकते हैं (त्रुटि-प्रवण) या 'निर्यातक' से बहुमुखी कार्यान्वयन का उत्तराधिकारी प्राप्त कर सकते हैं। विरासत को आंतरिक रूप से '@ ISA' सरणी के साथ दर्शाया गया है। – amon

3

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

perlobj से

:

प्रत्येक पैकेज एक विशेष सरणी @ISA कहा जाता है। @ISA सरणी में उस वर्ग के मूल वर्गों की सूची है, यदि कोई हो। इस सरणी की जांच तब की जाती है जब पर्ल विधि समाधान करता है, जिसे हम बाद में कवर करेंगे।

उदाहरण के लिए, यह एक त्रुटि है क्योंकि पर्ल न के बराबर सबरूटीन Foo::some_method फोन करने की कोशिश करेंगे:

sub Bar::some_method { 42 } 
my $obj = bless {}, 'Foo'; 
$obj->some_method; 

एक पैकेज में @ISA चर पर्ल बताता अन्य संकुल में विधि देखने के लिए, इसलिए यह कोड काम करेगा और Bar::some_method विधि का आह्वान करेगा।

sub Bar::some_method { 42 } 
my $obj = bless {}, 'Foo'; 
@Foo::ISA = qw(Bar); 
$obj->some_method; 

इसके लिए व्यावहारिक आवेदन विरासत है।

जैसा कि आमोन का उल्लेख है, @ISA को सीधे सेट करने की आवश्यकता नहीं है। parent प्रगा (और पुराना, अब base प्रज्ञा को हतोत्साहित) विरासत संबंध घोषित करता है और आपके लिए यह चर सेट करता है।

11

@Foo::ISA सरणी एक वैश्विक चर है जो कक्षाओं को Foo विरासत से प्राप्त करता है।

आम तौर पर, आपको सीधे @ISA में हेरफेर नहीं करना चाहिए; ऐसा करना एक संकेत है कि आप शायद पुराने पर्ल कोड देख रहे हैं।

आप एक विरासत संबंध, यह करने के लिए एक बेहतर तरीका घोषित करने के लिए चाहते हैं

use parent 'Exporter'; 

जो @ISA आप के लिए पर्दे के पीछे बदलाव करता है और यह भी कुछ अन्य उपयोगी सामान करता है।

आपके मामले में, जब आप

our @ISA = qw(Exporter) 

आप Exporter का एक उपवर्ग के रूप में अपने वर्ग की घोषणा कर रहे हैं। Exporter कक्षा import नामक एक विधि प्रदान करती है। तुम उसे क्यों चाहते हो? क्योंकि जब आप कहते हैं कि

use MyClass; 

क्या वास्तव में होता है:

BEGIN { 
    require 'MyClass.pm'; 
    MyClass->import; 
}; 

import प्रक्रिया स्वतः ही कहा जाता है हर बार किसी use अपने वर्ग है। वह विधि आप जो भी चाहें कर सकते हैं। (यदि आप चाहते हैं तो आप अपना खुद का import लिख सकते हैं) लेकिन आमतौर पर इसका उपयोग कॉलर के नामस्थान में प्रतीकों को आयात करने के लिए किया जाता है। Exporter आपके लिए क्या है।

हालांकि, Exporter भी अपनी import विधि निर्यात करता है, इसलिए आपको वास्तव में इसे और अधिक प्राप्त नहीं करना है। (यह एक बहुत अधिक समय लगा पहले तय हुई थी।) तो अब आप सिर्फ

use Exporter qw(import); 

कह सकते हैं और अपने पैकेज बिल्कुल @ISA साथ उलझे बिना import विधि मिल जाएगा।

6

ऑब्जेक्ट उन्मुख सोचें।

एक्सपोर्टर को केवल मॉड्यूल के रूप में नहीं, बल्कि वर्ग के रूप में सोचें।ISA के रूप में सोचें "है ए" जैसा कि में है "मेरा मॉड्यूल निर्यातक के उप-वर्ग" है।

आप जो कर रहे हैं वह एक्सपोर्टर क्लास के उप-वर्ग के रूप में आपके मॉड्यूल को घोषित कर रहा है जिसका अर्थ है कि आप एक्सपोर्टर क्लास की import विधि का उपयोग कर सकते हैं जो कि उपयोगी है।

वास्तव में यह समझाने के लिए कि निर्यातक क्या कर रहा है, आपको समझना होगा कि पर्ल नामस्थान का उपयोग करता है। कल्पना करें कि क्या आपके प्रोग्राम में एक चर है जिसे $total कहा जाता है, लेकिन आप जिस मॉड्यूल का उपयोग कर रहे हैं वह भी करता है। आपका $total वैरिएबल मॉड्यूल के $total चर के साथ हस्तक्षेप करेगा।

इसे रोकने के लिए, पर्ल नामस्थान का उपयोग करता है। आपका प्रोग्राम डिफ़ॉल्ट नामस्थानmain में संचालित होता है। आपके मॉड्यूल package फ़ंक्शन का उपयोग एक नया नेमस्पेस घोषित करने के लिए करते हैं। अब, आप और आपका मॉड्यूल सुरक्षित रूप से $total नामक चर का उपयोग कर सकते हैं। आपके प्रोग्राम में, यह वास्तव में $main::total है, और पैकेज में, यह $ पैकेज :: नाम :: कुल . If you want to use something from one _namespace_ in another, you can prepend the _namespace_ on it. Think of the $ फ़ाइल :: ढूंढें :: नाम and $ फ़ाइल :: खोजें :: डीआईआर variables you have when you use फ़ाइल :: खोजें '।

निर्यातक की import विधि क्या है आपके उप-स्थान (और यदि आप चाहते हैं, तो आपके चर) को अपने नेमस्पेस से वर्तमान नामस्थान में कॉपी करें। पर अपने मुख्य नेमस्पेस पर copy सबराउटिन पर की प्रतिलिपि File::Copy मॉड्यूल का उपयोग करके कल्पना करें। तुम अब भी इसका इस्तेमाल कर सकते हैं, लेकिन आप यह उस पर नाम स्थान का नाम देने के लिए होगा:

use File::Copy; 

... 

File::Copy::copy($from_file, $to_file); 

निर्यातक (और आयात विधि) के लिए धन्यवाद, किसी भी सबरूटीन्स आप अपने संकुल में डाल दिया @EXPORT सरणी कॉपी कर रहे हैं वर्तमान नामस्थान पर। इस प्रकार, आप इस तरह s copy` सबरूटीन फ़ाइल :: कॉपी पहुँच सकते हैं:

use File::Copy; 

... 

copy ($from_file, $to_file); 

यह भी कारण है कि आप our और नहीं my के रूप में इन चर के सभी घोषित करना चाहिए। my चर लिक्सिक रूप से स्कॉप्ड हैं और उन्हें घोषित किए जाने के बाहर एक्सेस नहीं किया जा सकता है। पैकेज चर (जैसे $File::Find::name) हो सकता है। Exporter के लिए अपने @EXPORT, और @EXPORT_OK सरणी खोजने के लिए, इन्हें पैकेज चर होने की आवश्यकता है।

अब, कार्यों के निर्यात की वांछनीयता ...

सबसे पुराने मॉड्यूल है कि हम जानते हैं और निर्यात सबरूटीन्स प्यार बिना सोचे समझे आता है। आप फ़ाइल :: कॉपी, फ़ाइल :: पथ, फ़ाइल :: ढूँढें, और आपके पास उनके उप-सूटियों तक तुरंत पहुंच है। ऐसा इसलिए है क्योंकि उन्होंने अपने subroutines @EXPORT सरणी में डाल दिया। यह एक समय में वांछनीय विचार था क्योंकि यह इन कार्यों को तुरंत आपके लिए उपलब्ध कराता है। File::Temp तरह

नए मॉड्यूल सबरूटीन्स आप आयात करना चाहते घोषित करने के लिए आप की आवश्यकता:

use File::Temp qw(tempdir); 

... 
my $temp_dir = tempdir; 

मैं आपके पास नहीं था कि qw(tempdir), मैं tempdir फ़ंक्शन का उपयोग नहीं कर सका।

इसे विनम्र माना जाता है। मॉड्यूल फ़ंक्शन आयात करने के लिए आपकी अनुमति मांग रहा है। यह subroutines @EXPORT_OK में डालकर किया जाता है। ये केवल अनुरोध पर निर्यात किया जाएगा।

यह बेहतर है क्योंकि आपको केवल वही चीज़ आयात करने की ज़रूरत नहीं है, जो आपको चाहिए। और, आप दस्तावेज कर रहे हैं जहां इन कार्यों को परिभाषित किया गया है।

ऑब्जेक्ट ओरिएंटेड मॉड्यूल कुछ भी निर्यात नहीं करते हैं और निर्यातक का उपयोग करने की आवश्यकता नहीं है। यह एक लंबा समय रहा है क्योंकि मैंने एक मॉड्यूल लिखा है जो निर्यातक का उपयोग करता है।

- हम के बारे में पैकेज चर यहां बात कर रहे हैं। पैकेज चर हर जगह दिखाई दे रहे हैं।

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