سؤال

أنا أرى أن كلا منهم المستخدمة في هذا البرنامج النصي أنا أحاول تصحيح و الأدب ليس واضحا.شخص ما يمكن أن الغموض هذا بالنسبة لي ؟

هل كانت مفيدة؟

المحلول

ديناميكية النطاق.بل هو مفهوم أنيق.كثير من الناس لا يستخدمونه أو فهمه.

أساسا التفكير my كما خلق وترسيخ متغير إلى كتلة واحدة من {}, A. K. A.نطاق.

my $foo if (true); # $foo lives and dies within the if statement.

لذلك my المتغير هو ما كنت تستخدم.بينما مع ديناميكية النطاق $var يمكن أن تعلن في أي مكان واستخدامها في أي مكان.حتى مع local كنت في الأساس تعليق استخدام هذا المتغير العالمي ، واستخدام "القيمة المحلية" للعمل معها.لذلك local يخلق المؤقتة نطاق متغير مؤقت.

$var = 4;
print $var, "\n";
&hello;
print $var, "\n";

# subroutines
sub hello {
     local $var = 10;
     print $var, "\n";
     &gogo; # calling subroutine gogo
     print $var, "\n";
}
sub gogo {
     $var ++;
}

يجب طباعة هذا:

4
10
11
4

نصائح أخرى

الجواب القصير هو أن my علامات متغير خاص في معجمي نطاق ، local علامات متغير خاص في دينامية نطاق.

فإنه من السهل أن نفهم my, لأن ذلك يخلق متغير محلي في بالمعنى المعتاد.هناك متغير جديد تم إنشاؤها ويمكن الوصول إليها فقط داخل أرفق المعجمية كتلة ، والتي عادة ما تتسم الأقواس المتعرجة.هناك بعض الاستثناءات مجعد هدفين القاعدة ، مثل:

foreach my $x (@foo) { print "$x\n"; }

ولكن هذا مجرد بيرل تفعل ما تعنيه.عادة لديك شيء من هذا القبيل:

sub Foo {
   my $x = shift;

   print "$x\n";
}

في هذه الحالة ، $x خاصة إلى روتين فرعي نطاقه محاطة الأقواس المعقوفة.الشيء المهم أن نلاحظ, و هذا هو عكس local, هو أن نطاق my المتغير هو محدد فيما يتعلق التعليمات البرمجية الخاصة بك كما هو مكتوب في الملف.انها الترجمة الوقت الظاهرة.

فهم local, تحتاج إلى التفكير في استدعاء المكدس من البرنامج أثناء تشغيله.عندما متغير local, هو تعريف من النقطة التي local بيان ينفذ على كل شيء أقل من ذلك على المكدس ، حتى تعود مرة أخرى حتى المكدس إلى المتصل من كتلة تحتوي على local.

هذا يمكن أن يكون مربكا في البداية ، والنظر في المثال التالي.

sub foo { print "$x\n"; }
sub bar { local $x; $x = 2; foo(); }

$x = 1;
foo(); # prints '1'
bar(); # prints '2' because $x was localed in bar
foo(); # prints '1' again because local from foo is no longer in effect

عندما foo ويسمى أول الوقت ، فإنه يرى القيمة العالمية $x الذي هو 1.عندما bar ويسمى local $x يعمل هذا يعيد العالمية $x على المكدس.الآن عندما foo ويسمى من bar, تعتبر القيمة الجديدة 2 $x.حتى الآن ليس خاص جدا ، لأن نفس الشيء قد حدث من دون دعوة local.السحر هو أنه عندما bar يعود علينا الخروج من نطاق ديناميكي إنشاؤه من قبل local $x السابق العالمية $x يعود إلى نطاق.لذلك النداء الأخير من foo, $x 1.

وسوف دائما تقريبا ترغب في استخدام my, منذ أن يعطيك المحلية المتغيرة تبحث عنه.مرة واحدة في القمر الأزرق ، local هو مفيد حقا أن تفعل أشياء باردة.

نقلا عن تعلم بيرل:

ولكن هو ذات التسمية المضللة ، أو على الأقل مضلل اسمه.صديقنا رقاقة Salzenberg يقول أنه إذا كان أي وقت مضى يحصل على فرصة العودة في آلة الزمن إلى عام 1986 و تعطي لاري قطعة واحدة من المشورة سوف يقول لاري الاتصال المحلية باسم "حفظ" بدلا من ذلك.[14] لأن المحلية في الواقع سيوفر معين العالمي المتغير قيمة بعيدا ، لذلك سيتم في وقت لاحق تلقائيا استعادة العالمي المتغير.(هذا صحيح:هذه ما يسمى "المحلية" المتغيرات في الواقع globals!) هذا حفظ و استعادة آلية نفس واحدة لقد رأينا بالفعل مرتين الآن في التحكم في متغير من حلقة foreach في @_ مجموعة من روتين المعلمات.

لذلك ، local يحفظ عالمي متغير القيمة الحالية ثم قم بتعيين إلى بعض شكل من قيمة فارغة.سوف ترى في كثير من الأحيان كانت ملتهم ملف كامل بدلا من أبرز مجرد خط:

my $file_content;
{
    local $/;
    open IN, "foo.txt";
    $file_content = <IN>;
} 

الدعوة local $/ يحدد إدخال سجل فاصل (القيمة التي بيرل توقف القراءة "خط" في) إلى قيمة فارغة ، مما تسبب في سفينة الفضاء المشغل من قراءة الملف بأكمله, لذلك لم يضرب إدخال سجل فاصل.

لا أصدق أن لا أحد لديه مرتبطة مارك جاسون مولاي' شاملة الاطروحات في هذا الشأن:

http://perldoc.perl.org/perlsub.html#Private-Variables-via-my()

على عكس المتغيرات الديناميكية التي أنشأتها المشغل المحلي, المعجمية المتغيرات أعلن مع بلدي مخفي تماما من العالم الخارجي ، بما في ذلك أي ودعا الوظائف الفرعية.وهذا صحيح إذا انها نفس فرعي يسمى من نفسها أو في أماكن أخرى--كل مكالمة يحصل نسخته.

http://perldoc.perl.org/perlsub.html#Temporary-Values-via-local()

المحلية يعدل المدرجة المتغيرات أن تكون "محلية" أن أرفق كتلة ، eval ، أو الملف-و إلى أي فرعي يسمى من داخل كتلة.المحلية فقط يعطي المؤقتة القيم العالمية (يعني حزمة) المتغيرات.فإنه لا يخلق المحلية متغير.هذا هو المعروف باسم ديناميكية تحديد النطاق.المعجمية النطاق مع والتي تعمل مثل C السيارات إعلانات.

أنا لا أعتقد أن هذا هو في كل شيء غير واضح ، عدا أن أقول أنه من خلال "المحلية أن أرفق كتلة" ما يعنيه ذلك هو أن الأصل في استعادة قيمة عندما كتلة خرجت.

حسنا جوجل يعمل حقا بالنسبة لك على هذا واحد: http://www.perlmonks.org/?node_id=94007

من الرابط:

ملخص سريع:'بلدي' يخلق جديد متغير, 'المحلية' مؤقتا يعدل قيمة متغير.

أي 'المحلية' مؤقتا يتغير قيمة المتغير, ولكن فقط ضمن نطاق كان موجودا في.

عموما استخدام بلدي بشكل لا تفعل أي شيء غريب.

من man perlsub:

على عكس المتغيرات الديناميكية التي تم إنشاؤها من قبل المشغل المحلي, المعجمية المتغيرات أعلن مع بلدي مخفي تماما عن العالم الخارجي ، بما في ذلك أي دعا الوظائف الفرعية.

لذا, تبسيط, my يجعل المتغير الخاص بك مرئية فقط حيث أعلن. local يجعلها مرئية أسفل الاستدعاءات أيضا.سوف تحتاج عادة إلى استخدام my بدلا من local.

حيرتك غير مفهومة.المعجمية النطاق إلى حد ما من السهل أن نفهم ولكن ديناميكية النطاق غير مفهوم.الوضع سوءا قبل أسماء my و local كونها غير دقيقة إلى حد ما (أو على الأقل unintuitive) لأسباب تاريخية.

my تعلن المعجمية متغير -- واحد التي مرئيا من وجهة الإعلان حتى نهاية أرفق كتلة (أو ملف).وهي مستقلة تماما عن أي متغيرات أخرى بنفس الاسم في ما تبقى من البرنامج.بل هو خاص إلى أن كتلة.

local, ومن ناحية أخرى تعلن مؤقت تغيير قيمة متغير عمومي.التغيير ينتهي في نهاية أرفق نطاق ، ولكن المتغير -- يجري العالمية -- مرئيا في أي مكان في البرنامج.

وكقاعدة عامة من الإبهام, استخدام my إعلان المتغيرات الخاصة بك ، local التحكم تأثير التغييرات على بيرل المدمج في المتغيرات.

للحصول على وصف أكثر دقة انظر مارك جاسون مولاي' المادة التعامل مع النطاق.

المحلية هي طريقة قديمة من التعريب من الأوقات بيرل فقط ديناميكية النطاق.تحديد النطاق المعجمي هو أكثر طبيعية بالنسبة للمبرمج و أكثر أمانا في كثير من الحالات.بلدي متغيرات تنتمي إلى نطاق (كتلة, حزمة, أو الملفات) التي يتم الإعلان عنها.

المتغيرات المحلية بدلا من ذلك في الواقع تنتمي إلى مساحة العالمي.إذا كنت تشير إلى المتغير $x المحلية ، هي في الواقع إشارة إلى $الرئيسية::x, وهو متغير عمومي.على عكس ما يوحي الاسم, جميع المحلية لا يتم دفع قيمة جديدة على كومة من قيم $الرئيسية::× حتى نهاية هذه الكتلة ، في الوقت الذي القيمة القديمة سيتم استعادتها.هذا هو ميزة مفيدة في حد ذاتها ولكنها ليست وسيلة جيدة المتغيرات المحلية لمجموعة من الأسباب (أعتقد ما يحدث عندما يكون لديك المواضيع!وأعتقد أن ما يحدث عند استدعاء روتين الذي يريد حقا أن استخدام العالمية التي لديك مترجمة!).ومع ذلك كان السبيل الوحيد إلى المتغيرات التي بدت مثل المتغيرات المحلية مرة أخرى في الأيام القديمة السيئة من قبل بيرل 5.نحن لا تزال عالقة معها.

"بلدي" متغيرات واضحة في كتلة القانون الحالي فقط."المحلية" المتغيرات هي أيضا مرئية أي وقت مضى حيث أنها كانت واضحة من قبل.على سبيل المثال, إذا كنت أقول "يا $ × ؛" استدعاء وظيفة فرعية, فإنه لا يمكن رؤية هذا المتغير $x.ولكن إذا كنت أقول "المحلية $/;" (null قيمة السجل فاصل) ثم قمت بتغيير طريقة القراءة من الملفات يعمل في وظائف الاتصال.

في الواقع, كنت دائما تقريبا تريد "بلدي" ، وليس "المحلية".

نظرة على التعليمات البرمجية التالية و انتاجها أن نفهم الفرق.

our $name = "Abhishek";

sub sub1
{
    print "\nName = $name\n";
    local $name = "Abhijeet";

    &sub2;
    &sub3;
}

sub sub2
{
    print "\nName = $name\n";
}

sub sub3
{
    my $name = "Abhinav";
    print "\nName = $name\n";
}


&sub1;

الناتج هو :

Name = Abhishek

Name = Abhijeet

Name = Abhinav

dinomite المثال من المحلية إلى إعادة تعريف سجل محدد هو الوقت الوحيد لدي ركض عبر في الكثير من البرمجة perl.أنا أعيش في محراب بيرل البيئة [الأمن برمجة], لكن في الحقيقة هو نادرا ما تستخدم نطاق في تجربتي.

&s;

sub s()
{
    local $s="5";
    &b;
    print $s;
}

sub b()
{
    $s++;
}

السيناريو أعلاه يطبع 6.

ولكن إذا كان لنا أن تغيير المحلية إلى أنه سيتم طباعة 5.

هذا هو الفرق.بسيطة.

أعتقد أن أسهل طريقة لتذكر هو هذا الطريق.بلدي يخلق متغير جديد.المحلية مؤقتا تغيير قيمة متغير موجودة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top