`& method (: function)` หมายถึงอะไร


15

อะไร&method(:function)หมายถึง? ตัวอย่างเช่นฉันมีสายนี้:

res = integrate(0, 1, a, &method(:function))

สองคำตอบที่ยอดเยี่ยม (จนถึงตอนนี้) โชคดีนะคุณ!
Cary Swoveland

คำตอบ:


13

สมมติว่าเรามีวิธี

def add_one(num)
  num + 1
end

และอาร์เรย์ของสตริง

arr = ["1", "2"]

เราต้องการที่จะรายการของสตริงเพื่อผลที่สอดคล้องกันของพวกเขาจากmapadd_one

เพื่อเริ่มต้นเราสามารถโทร

nums = arr.map(&:to_i)

นี่คือสิ่งเดียวกัน

nums = arr.map do |str|
  str.to_i
end

คุณสามารถดูอะไรแผนที่ (&: ชื่อ) หมายถึงในทับทิม? สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้

อย่างไรก็ตามมันจะไม่ทำงานในการโทร:

nums.map(&:add_one)

ทำไม? เพราะตัวเลขไม่มีวิธีในadd_oneตัว NoMethodErrorดังนั้นคุณจะได้รับ

ดังนั้นแทนที่จะให้เพียงชื่อวิธีที่ :add_oneคุณสามารถผ่านวิธีการที่ถูกผูกไว้ method(:add_one) :

nums.map(&method(:add_one))

ตอนนี้มากกว่าแต่ละ NUM ถูกนำมาใช้เป็นตัวรับสัญญาณสำหรับadd_oneวิธีการที่พวกเขาจะนำมาใช้เป็นข้อโต้แย้ง ดังนั้นมันจึงเหมือนกับ:

nums.map do |num|
  add_one(num)
end

หากต้องการยกตัวอย่างอื่นให้เปรียบเทียบสิ่งต่อไปนี้:

[1].map(&:puts)
# this is the same as [1].map { |num| num.puts }
# it raises NoMethodError

[1].map(&method(:puts))
# this is the same as [1].map { |num| puts num }
# it prints 1 successfully

nitpick: Object#methodผลตอบแทนผูกพัน ไม่ใช่Method UnboundMethodวิธีการคือผูกไว้กับผู้รับเพราะคุณกำลังเรียกมันบนอินสแตนซ์และมันจึงรู้ว่าอะไรselfคืออะไรในขณะที่Module#instance_methodคืนค่าUnboundMethodเพราะมันไม่สามารถรู้ได้ว่ามันจะถูกใช้ด้วยวิธีใด
Jörg W Mittag

@ JörgWMittag Ok ขอบคุณสำหรับการแก้ไขคุณถูกต้องฉันต้องผสมกับมัน.instance_methodเพราะฉันเพิ่งจะไปโดยหน่วยความจำ (มีข้อบกพร่อง)
สูงสุด pleaner

10

method(:function)เป็นการส่งข้อความ (บางครั้งเรียกว่าการเรียกเมธอด ) ไปยังผู้รับโดยนัย (เช่นself) มันกำลังส่งข้อความmethodไปยังผู้รับโดยปริยาย (เช่นself) ผ่าน:functionเป็นอาร์กิวเมนต์เพียงอย่างเดียว

:functionเป็นตัวอักษรคือมันเป็นสัญกรณ์ที่แท้จริงของSymbol เป็นชนิดข้อมูลที่แสดงถึง "ชื่อของบางสิ่ง"SymbolSymbol

คำนำหน้าเอกเครื่องหมาย&ประกอบการ "หนึบ" ซึ่งเป็นProcเป็นบล็อก คือช่วยให้คุณผ่านจุดProcที่คาดว่าบล็อก ถ้าวัตถุไม่ได้แล้วProcก็จะมีการส่งข้อความปล่อยให้มันแปลงตัวเองเป็นto_proc Proc(โอเปอเรเตอร์นั้นถูกกฎหมายในรายการอาร์กิวเมนต์เท่านั้นและสำหรับอาร์กิวเมนต์ล่าสุดเท่านั้นมันคือสองของ&sigil ในรายการพารามิเตอร์ซึ่ง "ม้วน" บล็อกเข้าไปในProcวัตถุ)

Procเป็นประเภทข้อมูลที่แสดงถึงรหัสที่ปฏิบัติการได้ เป็นคลาสไลบรารีหลักของรูบี้สำหรับรูทีนย่อยชั้นหนึ่ง

ดังนั้นสิ่งนี้ไม่เป็นเรียกmethodวิธีการเกี่ยวกับการselfที่มี:functionเป็นอาร์กิวเมนต์โทรto_procในค่าตอบแทน "เหยียด" ส่งผลให้Procวัตถุเป็นบล็อกและผ่านบล็อกว่าการเรียกร้องให้integrateบางสิ่งบางอย่างเช่นถ้าคุณได้เขียนเช่น

res = integrate(0, 1, a) do
  # something
end

methodวิธีการที่นี่มีแนวโน้มมากที่สุดที่Object#methodวิธีการที่จะส่งกลับผูก Methodวัตถุ

ดังนั้นโดยรวมแล้วมันค่อนข้างจะเท่ากับ

res = integrate(0, 1, a) do |*args, &block|
  function(*args, &block)
end

แต่แสดงออกในสิ่งที่เรียกกันทั่วไปว่า สไตล์ฟรีสไตล์

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