2013-06-20 4 views
7

मैं कैसे मैं पर्ल में क्या कर सकते हैं के बारे में सोच रहा हूँ कि मैं क्या सामान्यतः तुतलाना में कार्य करें:गतिशील चर

(defvar *verbose-level* 0) 
(defun my-function (... &key ((:verbose-level *verbose-level*) *verbose-level*) ...) ...) 

इसका मतलब यह है कि my-function शब्दाडंबर के वर्तमान स्तर पर चलाया जाता है, लेकिन मैं इसे एक पारित कर सकते हैं अलग स्तर है जो अपने सभी कॉल्स भी प्रभावित करेगा:

(defun f1 (&key ((:verbose-level *verbose-level*) *verbose-level*)) 
    (format t "~S: ~S=~S~%" 'f1 '*verbose-level* *verbose-level*) 
    (f2 :verbose-level 1) 
    (format t "~S: ~S=~S~%" 'f1 '*verbose-level* *verbose-level*) 
    (f2 :verbose-level (1+ *verbose-level*)) 
    (format t "~S: ~S=~S~%" 'f1 '*verbose-level* *verbose-level*)) 
(defun f2 (&key ((:verbose-level *verbose-level*) *verbose-level*)) 
    (format t "~S: ~S=~S~%" 'f2 '*verbose-level* *verbose-level*)) 
[17]> (f1) 
F1: *VERBOSE-LEVEL*=0 
F2: *VERBOSE-LEVEL*=1 
F1: *VERBOSE-LEVEL*=0 
F2: *VERBOSE-LEVEL*=1 
F1: *VERBOSE-LEVEL*=0 
NIL 
[18]> (f1 :verbose-level 4) 
F1: *VERBOSE-LEVEL*=4 
F2: *VERBOSE-LEVEL*=1 
F1: *VERBOSE-LEVEL*=4 
F2: *VERBOSE-LEVEL*=5 
F1: *VERBOSE-LEVEL*=4 

(ध्यान दें कि चर बाइंडिंग बाहर निकलने पर पुनर्स्थापित किए जाते हैं - यहां तक ​​कि असामान्य - कार्यों से)।

मैं पर्ल में ऐसा कुछ कैसे कर सकता हूं?

उदा। misc.pm में, मेरे पास our $verbose=0; है। मैं एक फ़ंक्शन कैसे लिखूं जो $verbose को इसके तर्क के मान से जोड़ देगा और बदले में अपना मूल्य बहाल करेगा?

उत्तर

10

वैश्विक चर के पर्ल की अवधारणा सीएल में विशेष चर के समान है।

आप कर सकते हैं "छाया" local के साथ एक वैश्विक चर का मान:

our $var = 1; 

func("before"); 

{ 
    # a block creates a new scope 
    local $var = 2; 
    func("inside"); 
} 

func("after"); 

sub func { say "@_: $var" } 

आउटपुट:

before: 1 
inside: 2 
after: 1 

यदि आप local एक मूल्य, नए मूल्य पूरे गतिशील गुंजाइश भर दिखाई दे रहा है , यानी सभी कार्यों में कहा जाता है। लेक्सिकल गुंजाइश किसी भी माध्यम से छोड़ी जाने के बाद पुराना मान बहाल किया जाता है (त्रुटियां, रिटर्न इत्यादि)। पूंछ कॉल गतिशील दायरे का विस्तार नहीं करते हैं, लेकिन स्कोप निकास के रूप में गिनती करते हैं।

ध्यान दें कि वैश्विक चर के पास पूरी तरह से योग्य नाम है। एक अलग पैकेज से, आपके पास

local $Other::Package::var = 3; 
Other::Package::func("from a package far, far away"); 

यह आमतौर पर एक कार्यात्मक (गैर OO) इंटरफेस के साथ पैकेज के लिए विन्यास प्रदान करने के लिए प्रयोग किया जाता है कुछ करना होगा। महत्वपूर्ण उदाहरण Carp और Data::Dumper हैं।

+1

पर्ल और सीएल के बीच समानताएं देखने के लिए यह बहुत ही मजेदार है। अलग-अलग नामस्थानों (सीएल: चर, कार्य, लेबल, धाराएं, ...; पर्ल: स्केलर, सरणी, हैंश, सब, आईओ, ...)।ओह, और सीएलओएस/मूस स्पष्ट रूप से संबंधित हैं – amon

3

यदि मैं आपको सही ढंग से समझता हूं, तो आपको स्थानीय रूप से एक फ़ंक्शन के अंदर एक वैश्विक चर को ओवरराइड करने की आवश्यकता है।

package my_package; 
our $verbose = 0; 

sub function { 
    my ($arg1, $arg2) = @_; # getting function arguments. 
    local $verbose = $arg1; 
} 

यह बदले में $verbose की पुरानी स्थिति को पुनर्स्थापित करेगा।

+0

धन्यवाद। क्या होगा यदि 'फ़ंक्शन' तर्क के बिना बुलाया जाता है? आईई, '$ arg1' अनबाउंड है। क्या मुझे 'स्थानीय $ verbose = परिभाषित $ arg1 का सहारा लेना है? $ arg1: $ verbose' या क्या एक सुंदर दृष्टिकोण है? – sds

+0

यदि आपने $ arg1 परिभाषित किया है तो आप 'स्थानीय $ verbose = $ arg1 लिख सकते हैं;'। –

+0

यह समझ में नहीं आता है। यदि '$ arg1' परिभाषित नहीं किया गया है, तो' $ verbose' अपरिभाषित होगा। आप क्या कर सकते हैं 'स्थानीय $ verbose = शिफ्ट; $ verbose = "डिफ़ॉल्ट" अगर $ verbose परिभाषित नहीं किया गया है; '(या परिभाषित-या असाइनमेंट ऑपरेटर का उपयोग करें: '$ verbose // =" default "')। – TLP

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