ในทับทิมบางวิธีมีเครื่องหมายคำถาม ( ?
) ที่ถามคำถามเช่นinclude?
นั้นหากถามว่าวัตถุที่เป็นปัญหานั้นรวมอยู่ด้วยสิ่งนี้จะส่งกลับค่าจริง / เท็จ
แต่ทำไมบางวิธีจึงมีเครื่องหมายอัศเจรีย์ ( !
) ที่คนอื่นไม่มี
มันหมายความว่าอะไร?
ในทับทิมบางวิธีมีเครื่องหมายคำถาม ( ?
) ที่ถามคำถามเช่นinclude?
นั้นหากถามว่าวัตถุที่เป็นปัญหานั้นรวมอยู่ด้วยสิ่งนี้จะส่งกลับค่าจริง / เท็จ
แต่ทำไมบางวิธีจึงมีเครื่องหมายอัศเจรีย์ ( !
) ที่คนอื่นไม่มี
มันหมายความว่าอะไร?
คำตอบ:
โดยทั่วไปวิธีการที่สิ้นสุดใน!
ระบุว่าวิธีการที่จะปรับเปลี่ยนวัตถุที่มันเรียกว่า ทับทิมเรียกสิ่งเหล่านี้ว่า " วิธีอันตราย " เพราะพวกเขาเปลี่ยนสถานะที่คนอื่นอาจมีการอ้างอิงถึง นี่คือตัวอย่างง่ายๆสำหรับสตริง:
foo = "A STRING" # a string called foo
foo.downcase! # modifies foo itself
puts foo # prints modified foo
สิ่งนี้จะออก:
a string
ในห้องสมุดมาตรฐานมีสถานที่มากมายที่คุณจะเห็นวิธีการตั้งชื่อที่คล้ายกันคู่หนึ่งที่มี!
และไม่มี สิ่งที่ไม่มีเรียกว่า "วิธีการที่ปลอดภัย" และพวกเขาจะส่งคืนสำเนาต้นฉบับที่มีการเปลี่ยนแปลงที่นำไปใช้กับสำเนาโดยที่ callee ไม่เปลี่ยนแปลง นี่คือตัวอย่างเดียวกันโดยไม่มี!
:
foo = "A STRING" # a string called foo
bar = foo.downcase # doesn't modify foo; returns a modified string
puts foo # prints unchanged foo
puts bar # prints newly created bar
ผลลัพธ์นี้:
A STRING
a string
โปรดทราบว่านี่เป็นเพียงการประชุม แต่มีคลาส Ruby มากมายที่ติดตาม นอกจากนี้ยังช่วยให้คุณสามารถติดตามสิ่งที่ได้รับการแก้ไขในรหัสของคุณ
save
และsave!
ในActiveRecord
เครื่องหมายอัศเจรีย์หมายถึงสิ่งต่าง ๆ มากมายและบางครั้งคุณไม่สามารถบอกอะไรได้มากไปกว่า "สิ่งนี้เป็นอันตรายระวังตัว"
ดังที่คนอื่น ๆ ได้กล่าวไว้ในวิธีการมาตรฐานมักใช้เพื่อระบุวิธีการที่ทำให้วัตถุกลายพันธุ์เอง แต่ไม่เสมอไป โปรดทราบว่าวิธีการมาตรฐานหลายเปลี่ยนรับของพวกเขาและไม่ได้มีเครื่องหมายอัศเจรีย์ ( pop
, shift
, clear
) และวิธีการบางอย่างที่มีเครื่องหมายอัศเจรีย์ไม่เปลี่ยนเครื่องรับของพวกเขา ( exit!
) ดูตัวอย่างบทความนี้
ห้องสมุดอื่น ๆ อาจใช้มันแตกต่างกัน ใน Rails มีเครื่องหมายอัศเจรีย์บ่อยครั้งซึ่งหมายความว่าวิธีการนี้จะทำให้เกิดข้อยกเว้นเกี่ยวกับความล้มเหลวแทนที่จะล้มเหลวอย่างเงียบ ๆ
มันเป็นแบบแผนการตั้งชื่อ แต่หลายคนใช้มันในวิธีที่ต่างกันอย่างละเอียด ในรหัสของคุณกฎง่ายๆคือใช้เมื่อใดก็ตามที่วิธีการทำบางอย่าง "อันตราย" โดยเฉพาะอย่างยิ่งเมื่อมีสองวิธีที่มีชื่อเดียวกันอยู่และหนึ่งในนั้นคือ "อันตราย" มากกว่าอีกวิธีหนึ่ง "อันตราย" อาจหมายถึงเกือบทุกอย่าง
นี้ตั้งชื่อการประชุมจะถูกยกขึ้นจากโครงการ
1.3.5 อนุสัญญาการตั้งชื่อ
ตามแบบแผนชื่อของโพรซีเดอร์ที่ส่งคืนค่าบูลีนมักจะลงท้ายด้วย ``? '' ขั้นตอนดังกล่าวเรียกว่าภาคแสดง
ตามแบบแผนชื่อของขั้นตอนที่เก็บค่าไว้ในตำแหน่งที่จัดสรรไว้ก่อนหน้านี้ (ดูหัวข้อ 3.4) มักจะลงท้ายด้วย ``! '' ขั้นตอนดังกล่าวเรียกว่าขั้นตอนการกลายพันธุ์ ตามแบบแผนค่าที่ส่งคืนโดยโพรซีเดอร์การกลายพันธุ์จะไม่ได้รับการระบุ
! โดยทั่วไปหมายถึงว่าวิธีการกระทำกับวัตถุแทนที่จะส่งกลับผลลัพธ์ จากหนังสือRuby Programming :
วิธีการที่เป็น "อันตราย" หรือปรับเปลี่ยนผู้รับอาจถูกตั้งชื่อด้วยการต่อท้าย "!"
มันถูกต้องที่สุดที่จะบอกว่าวิธีการที่มีบาง! เป็นเวอร์ชั่นที่อันตรายหรือน่าแปลกใจมากขึ้น มีวิธีการมากมายที่ทำให้กลายพันธุ์โดยไม่ใช้ Bang เช่น.destroy
และโดยทั่วไปจะมีวิธีเรียบที่มีทางเลือกที่ปลอดภัยกว่าใน lib หลัก
ตัวอย่างเช่นใน Array เรามี.compact
และ.compact!
ทั้งสองวิธีกลายพันธุ์อาร์เรย์ แต่.compact!
คืนค่าศูนย์แทนที่จะเป็นตัวเองหากไม่มีศูนย์ในอาร์เรย์ซึ่งน่าแปลกใจมากกว่าแค่คืนค่าตัวเอง
วิธีการเพียงคนเดียวไม่ใช่กรรมวิธีที่ฉันได้พบกับปังคือKernel
's .exit!
ซึ่งเป็นที่น่าแปลกใจมากกว่า.exit
เพราะคุณไม่สามารถจับSystemExit
ในขณะที่กระบวนการคือปิด
Rails และ ActiveRecord ยังคงแนวโน้มเช่นนี้ในการที่มันใช้ผลบางอย่างที่น่าแปลกใจเช่นเอฟเฟกต์.create!
ซึ่งทำให้เกิดข้อผิดพลาดในความล้มเหลว
จาก themomorohoax.com:
ปังสามารถใช้ในวิธีด้านล่างตามลำดับความชอบส่วนตัวของฉัน
1) วิธีการบันทึกที่ใช้งานทำให้เกิดข้อผิดพลาดหากวิธีการไม่ได้ทำในสิ่งที่มันบอกว่ามันจะ
2) วิธีการบันทึกที่ใช้งานบันทึกบันทึกหรือวิธีการบันทึกวัตถุ (เช่นแถบ!)
3) วิธีการทำสิ่งที่ "พิเศษ" เช่นโพสต์ไปยังบางแห่งหรือดำเนินการบางอย่าง
ประเด็นคือใช้ปังเมื่อคุณคิดจริงๆว่าจำเป็นหรือไม่เพื่อช่วยผู้พัฒนารายอื่นให้รำคาญใจที่ต้องตรวจสอบว่าทำไมคุณถึงใช้ปัง
ปังให้สองตัวชี้นำให้กับนักพัฒนาอื่น ๆ
1) ไม่จำเป็นต้องบันทึกวัตถุหลังจากเรียกใช้เมธอด
2) เมื่อคุณเรียกใช้เมธอด db จะถูกเปลี่ยน
http://www.themomorohoax.com/2009/02/11/when-to-use-a-bang-exclamation-point-after-rails-methods
คำอธิบายง่ายๆ:
foo = "BEST DAY EVER" #assign a string to variable foo.
=> foo.downcase #call method downcase, this is without any exclamation.
"best day ever" #returns the result in downcase, but no change in value of foo.
=> foo #call the variable foo now.
"BEST DAY EVER" #variable is unchanged.
=> foo.downcase! #call destructive version.
=> foo #call the variable foo now.
"best day ever" #variable has been mutated in place.
แต่ถ้าคุณเคยเรียกวิธีการdowncase!
ในคำอธิบายข้างต้นfoo
จะเปลี่ยนเป็นตัวพิมพ์เล็กอย่างถาวร downcase!
จะไม่ส่งคืนวัตถุสตริงใหม่ แต่แทนที่สตริงในสถานที่โดยสิ้นเชิงเปลี่ยนเป็นfoo
downcase ฉันขอแนะนำให้คุณอย่าใช้downcase!
จนกว่าจะจำเป็นจริงๆ
!
ฉันชอบที่จะคิดว่าสิ่งนี้เป็นการเปลี่ยนแปลงที่รุนแรงที่ทำลายทุกสิ่งที่ผ่านไปก่อนหน้านี้ เครื่องหมายตกใจหรือเครื่องหมายอัศเจรีย์หมายความว่าคุณกำลังทำการเปลี่ยนแปลงที่บันทึกไว้อย่างถาวรในรหัสของคุณ
หากคุณใช้ตัวอย่างเช่นวิธีการของรูบี้สำหรับการทดแทนทั่วโลกgsub!
การทดแทนที่คุณทำนั้นเป็นสิ่งถาวร
อีกวิธีหนึ่งที่คุณสามารถจินตนาการได้คือการเปิดไฟล์ข้อความและทำการค้นหาและแทนที่ตามด้วยการบันทึก !
ทำเช่นเดียวกันในรหัสของคุณ
สิ่งเตือนความจำที่มีประโยชน์อีกอย่างถ้าคุณมาจากโลกทุบตีก็sed -i
มีผลเช่นเดียวกันกับการเปลี่ยนแปลงอย่างถาวรที่บันทึกไว้
เรียกว่า "วิธีการทำลายล้าง" พวกเขามักจะเปลี่ยนสำเนาต้นฉบับของวัตถุที่คุณอ้างถึง
numbers=[1,0,10,5,8]
numbers.collect{|n| puts n*2} # would multiply each number by two
numbers #returns the same original copy
numbers.collect!{|n| puts n*2} # would multiply each number by two and destructs the original copy from the array
numbers # returns [nil,nil,nil,nil,nil]
Bottom line: !
วิธีการเพียงแค่เปลี่ยนค่าของวัตถุที่พวกเขาจะเรียกว่าในขณะที่วิธีการที่ไม่!
ส่งกลับค่าการจัดการโดยไม่ต้องเขียนเหนือวัตถุวิธีการที่ถูกเรียก
ใช้เฉพาะใน!
กรณีที่คุณไม่ได้วางแผนที่จะต้องการค่าดั้งเดิมที่เก็บไว้ในตัวแปรที่คุณเรียกว่าเมธอด
ฉันชอบทำสิ่งที่ชอบ:
foo = "word"
bar = foo.capitalize
puts bar
หรือ
foo = "word"
puts foo.capitalize
แทน
foo = "word"
foo.capitalize!
puts foo
ในกรณีที่ฉันต้องการเข้าถึงค่าเดิมอีกครั้ง
!
เปลี่ยนวัตถุแทนการส่งคืนสำเนาที่ถูกดัดแปลง
User.create!