จุดประสงค์ของ“!” คืออะไร และ“?” ท้ายชื่อเมธอด?


99

บางครั้งฉันเห็นวิธีการใน Ruby ที่มี "?" และ "!" ในตอนท้ายของพวกเขาเช่น:

name = "sample_string"
name.reverse
name.reverse!
name.is_binary_data?

ฉันสงสัยว่าจุดประสงค์ของพวกเขาคืออะไร? พวกเขาเป็นเพียงการเคลือบน้ำตาลแบบวากยสัมพันธ์หรือไม่?


คำตอบ:


160

มันเป็น "การเคลือบน้ำตาล" เพื่อให้อ่านง่าย แต่มีความหมายทั่วไป:

  • วิธีการสิ้นสุดใน!ดำเนินการบางอย่างเปลี่ยนแปลงอย่างถาวรหรืออาจเป็นอันตราย ; ตัวอย่างเช่น:
    • Enumerable#sortผลตอบแทนที่ได้รุ่นที่เรียงลำดับของวัตถุในขณะที่Enumerable#sort!ประเภทไว้ในสถานที่
    • ใน Rails ให้ActiveRecord::Base#saveส่งกลับเท็จหากการบันทึกล้มเหลวในขณะที่ActiveRecord::Base#save!มีข้อยกเว้น
    • Kernel::exitทำให้สคริปต์ออกในขณะที่Kernel::exit!ทำทันทีโดยข้ามตัวจัดการทางออกใด ๆ
  • วิธีการที่ลงท้ายด้วยการ?คืนค่าบูลีนซึ่งทำให้โค้ดไหลได้ง่ายขึ้นเหมือนประโยค - if number.zero?อ่านว่า "ถ้าตัวเลขเป็นศูนย์" แต่if number.zeroก็ดูแปลก ๆ

ในตัวอย่างของคุณname.reverseประเมินเป็นสตริงที่กลับรายการ แต่หลังจากname.reverse!บรรทัดเท่านั้นnameตัวแปรจะมีชื่อที่กลับรายการ name.is_binary_data?ดูเหมือนว่า "เป็นnameข้อมูลไบนารีหรือไม่"


22
ข้อสังเกตที่สำคัญอย่างหนึ่งคือคุณควรมีวิธีปังก็ต่อเมื่อคุณมีวิธีที่ไม่ปังที่สอดคล้องกัน ปังถูกใช้เพื่อแยกวิธีการเวอร์ชันที่ "น่าประหลาดใจยิ่งกว่า" ออกจากวิธีที่ "น่าประหลาดใจน้อยกว่า" หากคุณมีเพียงวิธีเดียวก็ไม่จำเป็นต้องมีความแตกต่างและคุณไม่ควรตั้งชื่อให้ปัง ดูArray#clearตัวอย่างเช่น มันล้างอาร์เรย์ การล้างอาร์เรย์โดยธรรมชาติจะทำให้มันกลายพันธุ์ ไม่มีอะไรน่าแปลกใจเกี่ยวกับเรื่องนี้ชื่อก็ชัดเจนแล้วดังนั้น: ไม่ปัง ดูruby-forum.com/topic/176830#773946
Jörg W Mittag

2
การเพิ่มสิ่งที่ @ JörgWMittagระบุไว้ตามRuby Style Guide : ชื่อของวิธีการที่อาจเป็นอันตราย (เช่นวิธีการที่แก้ไขตัวเองหรือข้อโต้แย้งออก! เครื่องหมายอัศเจรีย์ถ้ามีรุ่นปลอดภัยของวิธีการที่เป็นอันตรายที่
Tod Birdsall

2
ระวังนี่ไม่ใช่กรณีเสมอไป ยกตัวอย่างเช่นทับทิมอาร์เรย์ # concat docs.ruby-lang.org/en/2.0.0/Array.html#method-i-concat จุดที่คุณสามารถถูกไฟไหม้ได้อย่างไม่ดีคือ MyActiveRecordModel.column_names.concat (... ) แต่คุณต้องโคลนก่อนที่จะทำ concat
wintondeshong

15

เครื่องหมายคำถามระบุว่าเมธอดส่งคืนบูลีน ตอบแล้วที่นี่:

ตัวดำเนินการเครื่องหมายคำถามใน Ruby หมายถึงอะไร?

ปังบ่งชี้ว่าเมธอดกระทำกับวัตถุนั้นเอง ตอบแล้วที่นี่:

เหตุใดจึงใช้เครื่องหมายอัศเจรีย์ในวิธี Ruby?


8

ใน Ruby ?หมายความว่าเมธอดจะส่งคืนบูลีนและ!แก้ไขอ็อบเจ็กต์ที่ถูกเรียกใช้ พวกเขาอยู่ที่นั่นเพื่อปรับปรุงความสามารถในการอ่านเมื่อดูโค้ด


5

ตรงกันข้ามกับ - ฉันคิดว่า - ภาษาโปรแกรมส่วนใหญ่ ...

Ruby วิธีการได้รับอนุญาตให้ลงท้ายด้วยเครื่องหมายคำถามหรือเครื่องหมายอัศเจรีย์

ตามแบบแผนวิธีการที่ตอบคำถาม (เช่น Array # empty? จะคืนค่าจริงหากตัวรับว่าง) ลงท้ายด้วยเครื่องหมายคำถาม

วิธีการที่อาจเป็น "อันตราย" (เช่นวิธีที่แก้ไขตัวเองหรือข้อโต้แย้งทางออก! ฯลฯ ) โดยการประชุมลงท้ายด้วยเครื่องหมายอัศเจรีย์

จาก: http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/ ชื่อเมธอดส่วนตลก


1
วิธีการที่ลงท้ายด้วย?เรียกว่าวิธีการเพรดิเคต
Waseem

1

ระวังนี่ไม่ใช่กรณีเสมอไป ใช้ตัวอย่างเช่นทับทิมอาร์เรย์ # concat http://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-concat

MyActiveRecordModel.column_names.concat([url])ที่คุณสามารถรับที่ถูกเผาไหม้ไม่ดีเป็นสิ่งที่ต้องการ การโทรในภายหลังที่เกี่ยวข้องกับ MyActiveRecordModel จะพยายามค้นหาคอลัมน์ของ 'url' สำหรับ MyActiveRecordModel และ throw

แต่คุณต้องโคลนก่อนที่จะทำ concat โชคดีที่ชุดทดสอบของฉันจับชุดนี้ได้ แต่ .. หัวขึ้น!

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