ความหมายของ @_ ในภาษา Perl คืออะไร?


คำตอบ:


120

perldoc perlvarเป็นที่แรกในการตรวจสอบข้อมูลตัวแปร Perl ที่มีชื่อพิเศษ

การอ้างอิง:

@_: ภายในรูทีนย่อยอาร์เรย์@_มีพารามิเตอร์ที่ส่งผ่านไปยังรูทีนย่อยนั้น

รายละเอียดเพิ่มเติมสามารถพบได้ในperldoc perlsub (รูทีนย่อย Perl) ที่เชื่อมโยงจาก perlvar:

ข้อโต้แย้งใด ๆ @_ผ่านแสดงขึ้นในอาร์เรย์

ดังนั้นถ้าคุณเรียกว่าฟังก์ชั่นที่มีสองข้อโต้แย้งเหล่านั้นจะถูกเก็บไว้ในและ$_[0]$_[1]

อาร์เรย์@_เป็นอาร์เรย์ท้องถิ่นแต่องค์ประกอบที่มีนามแฝงสำหรับพารามิเตอร์เกลาที่เกิดขึ้นจริง โดยเฉพาะอย่างยิ่งหากมีการอัปเดตองค์ประกอบ $ _ [0] อาร์กิวเมนต์ที่เกี่ยวข้องจะได้รับการอัปเดต (หรือเกิดข้อผิดพลาดหากไม่สามารถอัปเดตได้)

ถ้าอาร์กิวเมนต์เป็นอาร์เรย์หรือองค์ประกอบแฮชซึ่งไม่มีอยู่เมื่อเรียกใช้ฟังก์ชันองค์ประกอบนั้นจะถูกสร้างขึ้นเฉพาะเมื่อ (และถ้า) มีการแก้ไขหรือมีการอ้างถึง (Perl เวอร์ชันก่อนหน้าบางตัวสร้างองค์ประกอบไม่ว่าจะกำหนดองค์ประกอบให้หรือไม่ก็ตาม) การกำหนดให้กับอาร์เรย์ทั้งหมด @_ จะลบนามแฝงนั้นออกและไม่อัปเดตอาร์กิวเมนต์ใด ๆ


ขอบคุณฉันเพิ่งคุ้นเคยกับการตรวจสอบ perldoc และฉันพบว่าหน้าเว็บมีประโยชน์: perldoc.perl.org/perlvar.html การสร้างต้นขั้ว perl ที่เปิดขึ้นบนเว็บก็ไม่เลว ... การจัดรูปแบบของหน้าเว็บช่วยฉันได้มาก
aschultz

27

โดยปกติคุณจะขยายพารามิเตอร์ที่ส่งผ่านไปยังส่วนย่อยโดยใช้@_ตัวแปร:

sub test{
  my ($a, $b, $c) = @_;
  ...
}

# call the test sub with the parameters
test('alice', 'bob', 'charlie');

นั่นคือวิธีที่อ้างว่าเป็นที่ถูกต้องโดยperlcritic


2
นี่เป็นครั้งหนึ่งที่ฉันไม่เห็นด้วยperlcriticโดยส่วนตัวแล้วฉันคิดว่าสิ่งนี้ดีที่สุดสำหรับฟังก์ชัน แต่สำหรับวิธีการหนึ่งมันมีประโยชน์ต่อshiftการอ้างอิงตัวเองจากนั้นแกะ@_อาร์เรย์ออก สิ่งนี้ทำให้ชัดเจนว่านี่เป็นวิธีการและวิธีการนี้ใช้พารามิเตอร์บางอย่าง
Joel Berger

ฉันน่าจะเคยใช้ / รู้จัก PERLCritic มาก่อน แต่ฉันไม่เคยใช้ ขอบคุณที่ใช้ในตัวอย่างนี้ บางครั้งสิ่งที่คุณอ้างถึงแบบตรงไปตรงมาสามารถช่วยให้ผู้อื่นเรียนรู้สิ่งใหม่ ๆ
aschultz

12

ครั้งแรกของการค้นหาperl @_กล่าวนี้ :

@_ คือรายการพารามิเตอร์ขาเข้าของย่อย

นอกจากนี้ยังมีคำอธิบายที่ยาวขึ้นและมีรายละเอียดมากขึ้นเช่นเดียวกัน


3
จริงๆแล้ว Hit แรกของการค้นหาโดย Google ของคุณจะเชื่อมโยงไปยังหน้านี้
Gabriel Southern

... เจ็ดปีต่อมาเวลาอินเทอร์เน็ตชั่วนิรันดร์ นั่นคือเหตุผลที่ฉันทั้งเชื่อมโยงกับผลลัพธ์แรกและถามถึงส่วนที่เกี่ยวข้อง: ขึ้นอยู่กับ Google เพียงอย่างเดียวจะไร้เดียงสามาก
Piskvor ออกจากอาคาร

1
จริงอยู่หลายปีต่อมา แต่ก็ยังน่ารำคาญที่ต้องอ่านคำตอบซึ่งหมายความว่าคุณควรให้ Google ตอบคำถาม เป็นข้อมูลที่ไม่มีจุดหมายสำหรับคนที่อ่านคำตอบอันเป็นผลมาจาก Googling
Gabriel Southern

2
ใช่การค้นหาเป็นขั้นตอนแรกที่ถูกต้อง แต่ไม่จำเป็นต้องใส่คำแนะนำในการค้นหาในคำตอบของคุณ เป็นข้อมูลที่ซ้ำซ้อนซึ่งไม่เพิ่มมูลค่าและเป็นเรื่องน่าขันเพราะหากมีคนติดตามลิงก์ค้นหาในคำตอบของคุณจะทำให้พวกเขากลับมาที่จุดเริ่มต้น
Gabriel Southern

1
คำตอบ "google it" ทั้งหมดนี้มีอายุแย่มาก😂
Austin Adams

11

คำถามคือความ@_ หมายใน Perl คำตอบสำหรับคำถามที่ว่าตราบเท่าที่$_หมายถึงมันใน Perl, @_ทำนองเดียวกันหมายความว่าพวกเขา

ดูเหมือนจะไม่มีใครได้กล่าวถึงนี้ด้านที่สำคัญของมันความหมาย - เช่นเดียวกับพวกเขา

ดังนั้นทั้งคู่จึงใช้เป็นสรรพนามหรือบางครั้งก็ใช้เป็นยาทา

โดยทั่วไปแล้วพวกเขาจะมีบรรพบุรุษเล็กน้อยแม้ว่าจะไม่เสมอไป


7

คุณยังสามารถใช้ shift สำหรับตัวแปรแต่ละตัวได้ในกรณีส่วนใหญ่:

$var1 = shift;

นี่เป็นหัวข้อที่คุณควรค้นคว้าเพิ่มเติมเนื่องจาก Perl มีวิธีการที่น่าสนใจมากมายในการเข้าถึงข้อมูลภายนอกภายในกิจวัตรย่อยของคุณ


3
เจ๋งใครก็ตามที่ให้คะแนนฉันเพียงแค่โพสต์วิธีอื่นในการทำสิ่งที่คล้ายกัน ฉันรู้ว่าฉันไม่ได้ตอบคำถามโดยตรงเพราะมีคนทำไปแล้ว แต่ฉันเสนอรูปแบบทางเลือกที่โปรแกรมเมอร์ perl ใหม่มักจะสับสน
hockfan86


2

นอกจากนี้หากฟังก์ชันส่งคืนอาร์เรย์ แต่ฟังก์ชันถูกเรียกใช้โดยไม่กำหนดข้อมูลที่ส่งคืนให้กับตัวแปรใด ๆ เช่นด้านล่าง ที่นี่เรียกว่า split () แต่ไม่ได้กำหนดให้กับตัวแปรใด ๆ เราสามารถเข้าถึงข้อมูลที่ส่งคืนได้ในภายหลังผ่าน @_:

$str = "Mr.Bond|Chewbaaka|Spider-Man";
split(/\|/, $str);

print @_[0]; # 'Mr.Bond'

นี้จะแยกสตริงและตั้งแถว$str@_


1

@ ใช้สำหรับอาร์เรย์

ในรูทีนย่อยหรือเมื่อคุณเรียกใช้ฟังก์ชันใน Perl คุณอาจส่งผ่านรายการพารามิเตอร์ ในกรณี@_นั้นสามารถใช้เพื่อส่งรายการพารามิเตอร์ไปยังฟังก์ชัน:

sub Average{

    # Get total number of arguments passed.
    $n = scalar(@_);
    $sum = 0;

    foreach $item (@_){

        # foreach is like for loop... It will access every
        # array element by an iterator
        $sum += $item;
    }

    $average = $sum / $n;

    print "Average for the given numbers: $average\n";
}

การเรียกใช้ฟังก์ชัน

Average(10, 20, 30);

หากคุณสังเกตโค้ดด้านบนให้ดูforeach $item(@_)บรรทัด ... ที่นี่จะส่งผ่านพารามิเตอร์อินพุต


use strictคุณควรเสมอ ดังนั้นฉันจึงแก้ไขฟังก์ชันย่อยของคุณ
EverythingRightPlace

0

อย่าพยายามแก้ไขตัวแปร @_ !!!! พวกเขาจะต้องไม่ถูกสัมผัส .. หรือคุณได้รับผลกระทบบางอย่างที่ไม่น่าสงสัย ตัวอย่างเช่น...

my $size=1234;
sub sub1{
  $_[0]=500;
}
sub1 $size;

ก่อนเรียก sub1 $ ขนาดมี 1234. แต่หลังจาก 500 (!!) คุณจะไม่แก้ไขค่านี้ !!! คุณสามารถส่งผ่านค่าตั้งแต่สองค่าขึ้นไปและเปลี่ยนค่าเหล่านี้ในรูทีนย่อยและค่าทั้งหมดจะเปลี่ยนไป! ฉันไม่เคยเห็นผลกระทบนี้อธิบาย โปรแกรมที่ฉันเคยเห็นยังปล่อยให้ @_ array แบบอ่านอย่างเดียว และเฉพาะที่คุณสามารถส่งผ่านตัวแปรได้อย่างปลอดภัยอย่าเปลี่ยนรูทีนย่อยภายในคุณต้องทำเช่นนั้นเสมอ:

sub sub2{
  my @m=@_;
  ....
}

กำหนด @_ ให้กับตัวแปรโพรซีเดอร์รูทีนย่อยโลคัลและทำงานกับตัวแปรต่อไป นอกจากนี้ในอัลกอริธึมการเรียกซ้ำแบบลึกบางตัวที่เรียกใช้อาร์เรย์ใหม่คุณอาจใช้วิธีนี้เพื่อลดหน่วยความจำที่ใช้สำหรับตัวแปรโลคัล เฉพาะในกรณีที่ส่งคืนอาร์เรย์ @_ เหมือนกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.