मुझे पता है कि myपर्ल में क्या है। यह एक चर को परिभाषित करता है जो केवल उस खंड के दायरे में मौजूद है जिसमें इसे परिभाषित किया गया है। क्या करता ourहै?
कैसे ourअलग है my?
मुझे पता है कि myपर्ल में क्या है। यह एक चर को परिभाषित करता है जो केवल उस खंड के दायरे में मौजूद है जिसमें इसे परिभाषित किया गया है। क्या करता ourहै?
कैसे ourअलग है my?
जवाबों:
महान सवाल: कैसे ourअलग है myऔर क्या करता ourहै?
संक्षेप में:
पर्ल 5 के बाद से उपलब्ध, myगैर-पैकेज चर घोषित करने का एक तरीका है, जो हैं:
$package_name::variable।दूसरी ओर, ourचर पैकेज चर हैं, और इस प्रकार स्वचालित रूप से:
$package_name::variable।एक चर की घोषणा के साथ ourआप use strictटाइपो चेतावनियों या संकलन-समय त्रुटियों को प्राप्त किए बिना उन्हें उपयोग करने के लिए चर को पूर्वनिर्धारित करने की अनुमति देता है । पर्ल 5.6 के बाद से, इसने अप्रचलित को बदल दिया है use vars, जो केवल फ़ाइल-स्कॉप्ड था, और जैसा कि वैसा ही नहीं है our।
उदाहरण के लिए, चर के लिए औपचारिक, योग्य नाम $xके अंदर package mainहै $main::x। घोषणा our $xकरने से आपको $xदंड के बिना नंगे चर का उपयोग करने की अनुमति मिलती है (यानी, परिणामस्वरूप त्रुटि के बिना), घोषणा के दायरे में, जब स्क्रिप्ट का उपयोग होता है use strictया use strict "vars"। गुंजाइश एक, या दो, या अधिक पैकेज, या एक छोटा ब्लॉक हो सकता है।
localचर नहीं बनाते हैं। यह से संबंधित नहीं है myऔर ourसब पर। localअस्थायी रूप से चर के मूल्य का समर्थन करता है और इसके वर्तमान मूल्य को साफ करता है।
ourचर पैकेज चर नहीं हैं। वे वैश्विक रूप से स्कोप्ड नहीं हैं, लेकिन लेक्सिकली-स्कॉप्ड वैरिएबल जैसे myवैरिएबल हैं। आप इसे निम्नलिखित कार्यक्रम में देख सकते हैं package Foo; our $x = 123; package Bar; say $x;:। यदि आप एक पैकेज चर को "घोषित" करना चाहते हैं, तो आपको उपयोग करने की आवश्यकता है use vars qw( $x );। our $x;एक लेक्सिकली-स्कोपेड वैरिएबल घोषित करता है जो पैकेज में उसी नाम वाले वैरिएबल से अलियास किया गया है जिसमें ourसंकलित किया गया था।
कार्टमैन और ओलाफुर के पेरलोनॉक्स और पर्लडॉक लिंक एक महान संदर्भ हैं - नीचे एक सारांश में मेरी दरार है:
myचर एक ही ब्लॉक द्वारा {}या एक ही फाइल के भीतर परिभाषित नहीं तो अगर {}एस में नहीं हैं । वे समान लेक्सिकल स्कोप / ब्लॉक के बाहर परिभाषित पैकेज / सबरूटीन से सुलभ नहीं हैं।
ourचर एक पैकेज / फ़ाइल के भीतर बंद कर दिए जाते हैं और किसी भी कोड से useया requireउस पैकेज / फ़ाइल से पहुंच योग्य होते हैं - उचित नामस्थान को प्रीपे करके संकुल के बीच नाम संघर्षों को हल किया जाता है।
बस इसे गोल करने के लिए, localवैरिएबल को "डायनामिक रूप से" स्कूप किया गया है, myवैरिएबल से अलग है कि वे उसी ब्लॉक के भीतर कहे जाने वाले सबरूटीन से भी सुलभ हैं।
myवैरिएबल लेक्सिकली स्कॉप्ड हैं [...] उसी फाइल के भीतर यदि {}s में नहीं है "। यह मेरे लिए उपयोगी था, धन्यवाद।
एक उदाहरण:
use strict;
for (1 .. 2){
# Both variables are lexically scoped to the block.
our ($o); # Belongs to 'main' package.
my ($m); # Does not belong to a package.
# The variables differ with respect to newness.
$o ++;
$m ++;
print __PACKAGE__, " >> o=$o m=$m\n"; # $m is always 1.
# The package has changed, but we still have direct,
# unqualified access to both variables, because the
# lexical scope has not changed.
package Fubb;
print __PACKAGE__, " >> o=$o m=$m\n";
}
# The our() and my() variables differ with respect to privacy.
# We can still access the variable declared with our(), provided
# that we fully qualify its name, but the variable declared
# with my() is unavailable.
print __PACKAGE__, " >> main::o=$main::o\n"; # 2
print __PACKAGE__, " >> main::m=$main::m\n"; # Undefined.
# Attempts to access the variables directly won't compile.
# print __PACKAGE__, " >> o=$o\n";
# print __PACKAGE__, " >> m=$m\n";
# Variables declared with use vars() are like those declared
# with our(): belong to a package; not private; and not new.
# However, their scoping is package-based rather than lexical.
for (1 .. 9){
use vars qw($uv);
$uv ++;
}
# Even though we are outside the lexical scope where the
# use vars() variable was declared, we have direct access
# because the package has not changed.
print __PACKAGE__, " >> uv=$uv\n";
# And we can access it from another package.
package Bubb;
print __PACKAGE__, " >> main::uv=$main::uv\n";
स्कूपिंग के साथ नकल पर्ल स्कूपिंग नियमों का एक अच्छा अवलोकन है। यह काफी पुराना है जिसकी ourचर्चा पाठ के मुख्य भाग में नहीं की गई है। इसे अंत में नोट्स सेक्शन में संबोधित किया जाता है ।
आलेख पैकेज चर और डायनेमिक स्कोप के बारे में बात करता है और यह कैसे लेक्सिकल वैरिएबल और लेक्सिकल स्कोप से भिन्न होता है।
myका उपयोग स्थानीय चर के लिए किया जाता है, जबकि ourवैश्विक चर के लिए उपयोग किया जाता है।
पर्ल में वैरिएबल स्कोपिंग पर अधिक पढ़ना : मूल बातें ।
${^Potato}वैश्विक है। यह उसी चर को संदर्भित करता है जहां आप इसका उपयोग करते हैं।
मैंने कभी पर्ल में कुछ शाब्दिक घोषणाओं के बारे में मुलाकात की, जिसने मुझे गड़बड़ कर दिया, जो इस प्रश्न से भी संबंधित हैं, इसलिए मैं यहां अपना सारांश जोड़ता हूं:
1. परिभाषा या घोषणा?
local $var = 42;
print "var: $var\n";
आउटपुट है var: 42। हालांकि हम यह नहीं बता सकते कि local $var = 42;परिभाषा या घोषणा है। लेकिन इस बारे में कैसे:
use strict;
use warnings;
local $var = 42;
print "var: $var\n";
दूसरा प्रोग्राम एक त्रुटि फेंक देगा:
Global symbol "$var" requires explicit package name.
$varपरिभाषित नहीं है, जिसका अर्थ है local $var;कि सिर्फ एक घोषणा! localएक चर घोषित करने का उपयोग करने से पहले , सुनिश्चित करें कि इसे पहले एक वैश्विक चर के रूप में परिभाषित किया गया है।
लेकिन यह असफल क्यों नहीं होगा?
use strict;
use warnings;
local $a = 42;
print "var: $a\n";
उत्पादन होता है: var: 42।
ऐसा इसलिए है $a, क्योंकि साथ ही $b, पर्ल में पूर्व-परिभाषित एक वैश्विक चर है। सॉर्ट फ़ंक्शन याद है ?
2. लेक्सिकल या ग्लोबल?
मैं पर्ल का उपयोग शुरू करने से पहले एक सी प्रोग्रामर था, इसलिए शाब्दिक और वैश्विक चर की अवधारणा मुझे सीधी लगती है: यह सिर्फ सी में ऑटो और बाहरी चर से मेल खाती है लेकिन छोटे अंतर हैं:
सी में, एक बाहरी चर किसी भी फ़ंक्शन ब्लॉक के बाहर परिभाषित एक चर है। दूसरी ओर, एक स्वचालित चर एक फ़ंक्शन ब्लॉक के अंदर परिभाषित एक चर है। ऐशे ही:
int global;
int main(void) {
int local;
}
पर्ल में रहते हुए, चीजें सूक्ष्म हैं:
sub main {
$var = 42;
}
&main;
print "var: $var\n";
आउटपुट है var: 42 । $varभले ही यह फ़ंक्शन ब्लॉक में परिभाषित किया गया हो, एक वैश्विक चर है! दरअसल पर्ल में, किसी भी चर को डिफ़ॉल्ट रूप से वैश्विक घोषित किया जाता है।
सबक हमेशा use strict; use warnings;एक पर्ल प्रोग्राम की शुरुआत में जोड़ना है , जो प्रोग्रामर को शाब्दिक चर को स्पष्ट रूप से घोषित करने के लिए मजबूर करेगा, ताकि हमें दी गई कुछ गलतियों से गड़बड़ न हो।
Perldoc हमारे की एक अच्छी परिभाषा है।
मेरे विपरीत, जो दोनों एक चर के लिए भंडारण को आवंटित करता है और वर्तमान गुंजाइश के भीतर उपयोग के लिए उस भंडारण के साथ एक साधारण नाम को जोड़ता है, हमारे सहयोगी वर्तमान पैकेज में पैकेज चर के साथ एक साधारण नाम को वर्तमान दायरे के भीतर उपयोग के लिए जोड़ते हैं। दूसरे शब्दों में, हमारे पास मेरे समान ही नियम हैं, लेकिन जरूरी नहीं कि एक चर बनाया जाए।
यह केवल कुछ हद तक प्रश्न से संबंधित है, लेकिन मैंने अभी एक (मेरे लिए) पर्ल सिंटैक्स की अस्पष्ट बिट की खोज की है जिसे आप "हमारे" (पैकेज) चर के साथ उपयोग कर सकते हैं जिसे आप "मेरे" (स्थानीय) के साथ उपयोग नहीं कर सकते हैं चर।
#!/usr/bin/perl
our $foo = "BAR";
print $foo . "\n";
${"foo"} = "BAZ";
print $foo . "\n";
आउटपुट:
BAR
BAZ
यदि आप 'हमारे' को 'मेरे' में बदलते हैं तो यह काम नहीं करेगा।
perl -e "my $foo = 'bar'; print $foo; ${foo} = 'baz'; pr int $foo"आउटपुट: barbaz perl -e "my $foo = 'bar'; print $foo; ${"foo"} = 'baz'; print $foo"आउटपुट: barbaz perl -e "my $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"आउटपुट: barbar तो मेरे परीक्षण में मैं एक ही जाल में गिर गया। $ {foo} $ foo के समान है, कोष्ठक प्रक्षेप करते समय उपयोगी होते हैं। $ {"foo"} वास्तव में $ main :: {} पर एक नज़र है जो मुख्य प्रतीक तालिका है, जैसे कि केवल पैकेज स्कूप्ड चर होते हैं।
perl -e "package test; our $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"कार्य है, इस संदर्भ में $ {"फू"} अब $ {"परीक्षण :: फू"} के बराबर है। प्रतीक चिह्न और ग्लोब के बारे में कुछ जानकारी है, जैसा कि एडवांस्ड पर्ल प्रोग्रामिंग बुक करती है। मेरी पिछली गलती के लिए क्षमा करें।
print "package is: " . __PACKAGE__ . "\n";
our $test = 1;
print "trying to print global var from main package: $test\n";
package Changed;
{
my $test = 10;
my $test1 = 11;
print "trying to print local vars from a closed block: $test, $test1\n";
}
&Check_global;
sub Check_global {
print "trying to print global var from a function: $test\n";
}
print "package is: " . __PACKAGE__ . "\n";
print "trying to print global var outside the func and from \"Changed\" package: $test\n";
print "trying to print local var outside the block $test1\n";
इसे आउटपुट करेंगे:
package is: main
trying to print global var from main package: 1
trying to print local vars from a closed block: 10, 11
trying to print global var from a function: 1
package is: Changed
trying to print global var outside the func and from "Changed" package: 1
trying to print local var outside the block
स्क्रिप्ट का उपयोग करने का प्रयास करते समय "सख्त का उपयोग करें" इस मामले में विफलता मिलेगी:
Global symbol "$test1" requires explicit package name at ./check_global.pl line 24.
Execution of ./check_global.pl aborted due to compilation errors.
बस निम्नलिखित कार्यक्रम का उपयोग करने का प्रयास करें:
#!/usr/local/bin/perl
use feature ':5.10';
#use warnings;
package a;
{
my $b = 100;
our $a = 10;
print "$a \n";
print "$b \n";
}
package b;
#my $b = 200;
#our $a = 20 ;
print "in package b value of my b $a::b \n";
print "in package b value of our a $a::a \n";
#!/usr/bin/perl -l
use strict;
# if string below commented out, prints 'lol' , if the string enabled, prints 'eeeeeeeee'
#my $lol = 'eeeeeeeeeee' ;
# no errors or warnings at any case, despite of 'strict'
our $lol = eval {$lol} || 'lol' ;
print $lol;
ourऔर myअलग क्यों हैं ? यह उदाहरण कैसे दिखाता है?
हमें लगता है कि वास्तव में एक दुभाषिया क्या है: यह कोड का एक टुकड़ा है जो स्मृति में मूल्यों को संग्रहीत करता है और एक प्रोग्राम में निर्देश देता है कि यह उन मूल्यों को उनके नामों तक पहुंच प्रदान करता है, जो इन निर्देशों के अंदर निर्दिष्ट हैं। तो, एक दुभाषिया का बड़ा काम नियमों को आकार देना है कि हम उन निर्देशों में नामों का उपयोग कैसे करें, जो दुभाषिया स्टोर करता है।
"मेरे" का सामना करने पर, दुभाषिया एक शाब्दिक चर बनाता है: एक नामित मूल्य जो दुभाषिया केवल तब तक पहुंच सकता है जब यह एक ब्लॉक निष्पादित करता है, और केवल उस वाक्यविन्यास ब्लॉक के भीतर से। "हमारे" का सामना करने पर, दुभाषिया पैकेज चर का एक शाब्दिक उपनाम बनाता है: यह एक नाम को बांधता है, जिसे दुभाषिया माना जाता है तब से एक शाब्दिक चर के नाम के रूप में संसाधित होने तक, ब्लॉक के समाप्त होने तक, पैकेज के मूल्य तक एक ही नाम के साथ चर।
इसका प्रभाव यह है कि आप तब दिखावा कर सकते हैं कि आप एक शाब्दिक चर का उपयोग कर रहे हैं और पैकेज चर की पूरी योग्यता पर 'सख्त उपयोग' के नियमों को दरकिनार कर रहे हैं। चूंकि दुभाषिया स्वचालित रूप से पैकेज चर बनाता है जब वे पहली बार उपयोग किए जाते हैं, "हमारे" का उपयोग करने का दुष्प्रभाव यह भी हो सकता है कि दुभाषिया एक पैकेज चर भी बनाता है। इस मामले में, दो चीजें बनाई जाती हैं: एक पैकेज चर, जिसे दुभाषिया हर जगह से एक्सेस कर सकता है, बशर्ते वह ठीक से नामित हो, जैसा कि 'सख्त उपयोग' (इसके पैकेज और दो कॉलन के नाम से पहले से), और इसके शाब्दिक उपनाम से अनुरोध किया गया है ।
सूत्रों का कहना है: