لماذا تحتاج $ عند الوصول إلى عناصر المصفوفة والتجزئة في Perl؟

StackOverflow https://stackoverflow.com/questions/153644

  •  03-07-2019
  •  | 
  •  

سؤال

نظرًا لأن المصفوفات والتجزئة يمكن أن تحتوي فقط على كميات قياسية في Perl، فلماذا يتعين عليك استخدام $ لإخبار المترجم أن القيمة هي عددية عند الوصول إلى عناصر المصفوفة أو التجزئة؟بمعنى آخر، على افتراض أن لديك مصفوفة @myarray والتجزئة %myhash, لماذا عليك أن تفعل:

$x = $myarray[1];
$y = $myhash{'foo'};

بدلاً من مجرد القيام بما يلي:

$x = myarray[1];
$y = myhash{'foo'};

لماذا ما ورد أعلاه غامض؟

ألن يكون رمز بيرل غير قانوني إذا لم يكن سوى $ في ذلك المكان؟على سبيل المثال، أليست كل ما يلي غير قانونية في لغة بيرل؟

@var[0];
@var{'key'};
%var[0];
%var{'key'};
هل كانت مفيدة؟

المحلول

الشرائح ليست غير قانونية:

@slice = @myarray[1, 2, 5];
@slice = @myhash{qw/foo bar baz/};

وأظن أن هذا جزء من سبب حاجتك إلى تحديد ما إذا كنت تريد الحصول على قيمة واحدة من التجزئة/المصفوفة أم لا.

نصائح أخرى

لقد استخدمت للتو

my $x = myarray[1];

في أحد البرامج، ولدهشتي، إليك ما حدث عندما قمت بتشغيله:

$ perl foo.pl 
Flying Butt Monkeys!

وذلك لأن البرنامج بأكمله يبدو كالتالي:

$ cat foo.pl 
#!/usr/bin/env perl

use strict;
use warnings;

sub myarray {
  print "Flying Butt Monkeys!\n";
}

my $x = myarray[1];

لذلك يستدعي المصفوفة الخاصة روتينًا فرعيًا ويمرره مرجعًا إلى مصفوفة مجهولة تحتوي على عنصر واحد، 1.

وهذا سبب آخر لحاجتك إلى التوقيع عند الوصول إلى المصفوفة.

يمنحك السيجيل نوع الإرجاع للحاوية.لذلك إذا بدأ شيء بـ @, ، أنت تعلم أنه يقوم بإرجاع قائمة.إذا بدأ ب $, ، تقوم بإرجاع العددية.

الآن إذا كان هناك معرف فقط بعد السيجيل (مثل $foo أو @foo, ، فهو وصول متغير بسيط.إذا تبعه أ [, ، فهو عبارة عن وصول إلى مصفوفة، إذا كان متبوعًا بـ a {, ، إنه وصول إلى التجزئة.

# variables
$foo
@foo

# accesses
$stuff{blubb} # accesses %stuff, returns a scalar
@stuff{@list} # accesses %stuff, returns an array
$stuff[blubb] # accesses @stuff, returns a scalar
              # (and calls the blubb() function)
@stuff[blubb] # accesses @stuff, returns an array

بعض اللغات البشرية لها مفاهيم متشابهة جدًا.

ومع ذلك، وجد العديد من المبرمجين هذا الأمر مربكًا، لذا يستخدم Perl 6 سيجيلًا ثابتًا.

بشكل عام، يريد مترجم Perl 5 أن يعرف في وقت الترجمة ما إذا كان هناك شيء ما في القائمة أو في سياق عددي، لذلك بدون الشعار الرئيسي ستصبح بعض المصطلحات غامضة.

هذا بيرل صالح: @var[0].إنها شريحة مصفوفة بطول واحد. @var[0,1] ستكون شريحة مصفوفة بطول اثنين.

@var['key'] غير صالح بيرل لأنه لا يمكن فهرسة المصفوفات إلا بالأرقام ، والآخران (%var[0] and %var['key']) ليست لغة Perl صالحة لأن شرائح التجزئة تستخدم {} لفهرسة التجزئة.

@var{'key'} و @var{0} كلاهما شرائح تجزئة صالحة، بالرغم من ذلك.من الواضح أنه ليس من الطبيعي أن تأخذ شرائح بطول واحد، ولكن هذا صحيح بالتأكيد.

يرى قسم الشريحة من perldata perldocلمزيد من المعلومات حول التقطيع في بيرل.

لقد أشار الناس بالفعل إلى أنه يمكن أن يكون لديك شرائح وسياقات، ولكن السيجيلات موجودة لفصل الأشياء التي تعتبر متغيرات عن كل شيء آخر.ليس من الضروري أن تعرف كل الكلمات الرئيسية أو أسماء الإجراءات الفرعية لاختيار اسم متغير معقول.إنها واحدة من الأشياء الكبيرة التي أفتقدها في لغة Perl في اللغات الأخرى.

أستطيع أن أفكر في طريقة واحدة لذلك

$x = myarray[1];

غامض - ماذا لو أردت مصفوفة تسمى m؟

$x = m[1];

كيف يمكنك معرفة ذلك بصرف النظر عن تطابق التعبير العادي؟

وبعبارة أخرى، فإن بناء الجملة موجود لمساعدة مترجم بيرل، حسنًا، في الترجمة!

في Perl 5 (سيتم تغييره في Perl 6) تشير العلامة إلى سياق من تعبيرك.

  • تريد عددًا معينًا من التجزئة، لذا فهو كذلك $hash{key}.
  • تريد قيمة فتحة معينة خارج المصفوفة، لذا فهي كذلك $array[0].

ومع ذلك، كما أشار زيجدون، شرائح قانونية.يقومون بتفسير تلك التعبيرات في أ قائمة سياق.

  • تريد قوائم ذات قيمة واحدة في التجزئة @hash{key} يعمل
  • ولكن أيضًا القوائم الأكبر تعمل أيضًا، مثل @hash{qw<key1 key2 ... key_n>}.

  • تريد بضع فتحات من مجموعة @array[0,3,5..7,$n..$n+5] يعمل

  • @array[0] هي قائمة بالحجم 1.

لا يوجد "سياق تجزئة"، لذلك لا يوجد أيضًا %hash{@keys} ولا %hash{key} لها معنى.

لذلك لديك "@" + "array[0]" <=> < sigil = context > + < تعبير الفهرسة > كتعبير كامل.

يوفر الشعار سياق الوصول:

  • $ يعني سياق العددية (متغير قياسي أو عنصر واحد من التجزئة أو صفيف)
  • @ تعني السياق قائمة (صفيف كامل أو شريحة من التجزئة أو صفيف)
  • % هو تجزئة كاملة

في Perl 5، تحتاج إلى سيجيلز ($ و @) لأن التفسير الافتراضي لمعرف الكلمات المفردة هو استدعاء روتين فرعي (وبالتالي يلغي الحاجة إلى استخدام & في معظم الحالات ).

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