คุณกำลังทำงานกับจำนวนเต็ม แต่คุณต้องการใช้วิธีสตริง (เช่น gsub
) แทน
คุณทำอะไรได้บ้าง
แปลงเป็นสตริง (ด้วย to_s
) จากนั้นแปลงกลับเป็นจำนวนเต็ม (ด้วย to_i
)
ตัวอย่างเช่น :
คุณสามารถแปลง Integer
1 ถึง String
“1”.
จากนั้นคุณสามารถใช้เมธอดจากคลาสใหม่ได้ ซึ่งจะช่วยให้คุณทำสิ่งที่ไม่เคยทำได้มาก่อน
จำไว้ว่าใน Ruby…
ทุกอ็อบเจ็กต์เชื่อมโยงกับคลาส และทุกคลาสมีชุดเมธอดเฉพาะ
ในบทความนี้ คุณจะได้เรียนรู้เกี่ยวกับ :
- วิธีการแปลงใดบ้างที่มีอยู่ใน Ruby
- ความแตกต่างระหว่างพวกเขาคืออะไร!
- วิธีเลือกสิ่งที่ถูกต้องในสถานการณ์ต่างๆ
มาทำสิ่งนี้กันเถอะ!
วิธีการแปลงแบบสั้น (to_s, to_i)
คุณคงคุ้นเคยกับวิธีการแปลงกลุ่มแรกนี้แล้ว
วิธีการเช่น :
- to_i
- to_s
- to_a
เมธอดเหล่านี้ส่งคืนอ็อบเจ็กต์ใหม่ของคลาสเฉพาะที่แสดงถึงอ็อบเจ็กต์ปัจจุบัน
ตัวอย่างเช่น :
(1..10).to_a # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
สิ่งนี้บอกว่า :
“ฉันต้องการแปลง
Range
1..10 ลงในArray
ที่แสดงถึงช่วงนั้น”
มีหลายวิธีที่ Ruby เรียกวิธีการแปลงเหล่านี้ให้คุณโดยปริยาย
เช่นเดียวกับการแก้ไขสตริง:
"#{1}"
เรียก 1.to_s
สำหรับคุณแม้ว่าคุณจะไม่เห็นก็ตาม
คุณสามารถตรวจสอบตัวเองด้วยรหัสนี้ :
module Log def to_s puts "to_s called" super end end class Integer prepend Log end puts "#{1}" # "to_s called"
หมายเหตุ :คุณต้องใช้
Fixnum
แทนInteger
หากคุณใช้ Ruby 2.3 หรือเก่ากว่า หรือดีกว่านั้น อัปเดตเวอร์ชัน Ruby ของคุณ 🙂
วิธีการเหล่านี้ค่อนข้างอนุญาตและไม่ควรทำให้เกิดข้อยกเว้น
ตัวอย่างเช่น :
"aaaaaa".to_i # 0
0
นี้ อาจทำให้คุณประหลาดใจ
แต่นั่นคือสิ่งที่คุณได้รับเมื่อคุณเรียก to_i
ในสตริงที่ไม่มีจำนวนเต็ม
ดังที่คุณเห็นในบทความนี้ มีวิธีการที่เข้มงวดกว่านี้ .
วิธีการแปลงแบบยาว (to_str, to_int)
ตอนนี้:
ถ้าเรามีวิธีการแปลงแบบสั้นเหล่านั้น เหตุใดเราจึงต้องใช้วิธีการเช่น to_str
, หรือ to_int
?
ต่างกันอย่างไร
ความแตกต่างอยู่ที่ความตั้งใจ
ทุกคลาส Ruby (ยกเว้น BasicObject
) ใช้ to_s
วิธีการส่งคืนตัวเองเป็นการแสดงสตริงบางประเภท
แต่เพียงเพราะคลาสส่งคืนสตริง ไม่ได้หมายความว่าคลาสจะทำงานเหมือนสตริง!
มาดูตัวอย่างกัน :
"" + 1 # TypeError: no implicit conversion of Fixnum into String
คิดถึงสิ่งนี้ :
สตริงว่างบวกจำนวนเต็มควรส่งคืนอะไร
ไม่รู้สิ
คุณสามารถพูดว่า “1” (สตริงที่มีหมายเลขหนึ่ง)
แต่ทำไม?
นั่นไม่ใช่สิ่งที่คนส่วนใหญ่คาดหวังในกรณีนี้
ไม่สมเหตุสมผลที่จะรวมเข้าด้วยกัน… นั่นเป็นเหตุผลที่เราได้รับ TypeError
.
และแม้ว่าจะได้รับอนุญาตก็ตาม
แล้วนี่ไง :
"" + {}
นั่นคือสตริงว่างบวกกับแฮชที่ว่างเปล่า
ไม่สมเหตุสมผลเลย!
ดังนั้น Ruby แทนที่จะตรวจสอบว่าอ็อบเจกต์อื่นเป็นสตริงหรือไม่ ซึ่งไม่เป็นผลดีต่อ Polymorphism มันจะตรวจสอบว่ามันทำหน้าที่เหมือนสตริงหรือไม่
นั่นคือที่ที่ to_str
วิธีการเข้ามา
คลาสเดียวที่ใช้ to_str ใน Ruby 2.5 :
String
NameError::message
Warning::buffer
วิธีการใช้วิธีการแปลงของคุณเอง
คุณสามารถใช้ to_str
ในชั้นเรียนใดก็ได้
แล้วคุณจะใช้งานได้เหมือนสตริง
นี่คือตัวอย่าง :
class Cat def to_str "meow" end end "" + Cat.new # "meow"
แต่ ไม่ควรทำสิ่งนี้ เว้นแต่ชั้นเรียนของคุณจะเทียบเท่ากับสตริง .
ใช้ to_s
แทน
อีกอย่าง นี่ไม่ใช่แค่สำหรับ +
วิธีการ
นอกจากนี้ยังใช้ในที่อื่นๆ ที่มีเพียงวัตถุคล้ายสตริงเท่านั้นที่เข้าท่า
ถูกใจ :
[1,2,3].join(",")
วิธีการแปลงแบบยาวอื่นๆ เช่น to_int
&to_hash
ให้เป็นไปตามตรรกะเดียวกัน
เราจึงมีวิธีการต่างๆ เหล่านี้
วิธีใช้ Wrapper Conversion
หากคุณยังไม่มีวิธีการแปลงที่เพียงพอ… ไม่ต้องกังวลเพราะฉันมีวิธีอื่นให้คุณอีกสองสามวิธี!
ฉันชอบเรียกสิ่งเหล่านี้ว่า “Conversion Wrappers”
พวกเขา :
- Array()
- จำนวนเต็ม()
- แฮช[]
นั่นเป็นวิธีที่ดูผิดปกติ!
สังเกตวงเล็บ &วงเล็บเหลี่ยม…
…เป็นสิ่งเดียวที่แยกเมธอดเหล่านี้ออกจากชื่อคลาสได้
จุดประสงค์ของสิ่งเหล่านี้คืออะไร
Array() จะแปลงอะไรก็ได้ให้เป็นอาร์เรย์
นี่คือตัวอย่างบางส่วนสำหรับคุณ :
Array(nil) # [] Array([]) # [] Array(1) # [1] Array("") # [""]
ตรรกะอะไรเนี่ย???
วิธีนี้เป็นไปตามชุดกฎที่เฉพาะเจาะจงมาก :
- หากวัตถุตอบสนองต่อ
to_ary
, หรือto_a
มันจะเรียกมันว่า &คืนค่า - มิฉะนั้น มันจะวางวัตถุไว้ในอาร์เรย์ว่าง &ส่งคืน
ที่อธิบายพฤติกรรมที่แสดงข้างต้น
สิ่งนี้มีประโยชน์หากคุณกำลังเขียนวิธีการที่คาดหวังอาร์เรย์ แต่อาจได้รับสิ่งอื่นและทำให้วิธีการของคุณขัดข้องทั้งแอปพลิเคชัน คุณสามารถตรวจสอบว่าเป็นอาร์เรย์ได้โดยส่งต่อไปยัง Array()
ก่อนเพื่อหลีกเลี่ยงสิ่งนั้น
ตอนนี้ Integer()
.
มีกฎพิเศษบางอย่าง :
- หากวัตถุเป็นสตริง &เนื้อหาของสตริงสอดคล้องกับการแสดงตัวเลขที่ถูกต้องใน Ruby อย่างเคร่งครัด วิธีการนี้จะคืนค่าจำนวนเต็ม เพิ่ม
ArgumentError
หากรูปแบบไม่ถูกต้อง - ถ้าวัตถุไม่ใช่สตริง จะพยายามเรียก
to_int
แล้วto_i
. - มันจะขึ้น
TypeError
หากไม่สามารถแปลงวัตถุเป็นInteger
ที่ถูกต้องได้ โดยใช้วิธีการแปลง
ตัวอย่าง :
Integer(1) # 1 Integer("25") # 25 Integer("abc123") # ArgumentError (invalid value for Integer(): "abc123") Integer([]) # TypeError (can't convert Array into Integer)
Integer()
นี้ วิธีนี้จะมีประโยชน์หากคุณต้องการให้แน่ใจ 100% ว่าคุณกำลังทำงานกับ Integer
ที่ถูกต้อง .
ตอนนี้ Hash[]
.
คุณสามารถส่งผ่านอาร์เรย์ของ องค์ประกอบคู่ เพื่อรับแฮชใหม่:
Hash[[["a", 1], ["b", 2], ["c", 3]]] # {"a"=>1, "b"=>2, "c"=>3}
มีประโยชน์หากคุณกำลังสร้างแฮชโดยการรวมองค์ประกอบของสองอาร์เรย์ หรือใช้วิธีอย่างแผนที่
สรุป
คุณได้เรียนรู้เกี่ยวกับวิธีการแปลงที่แตกต่างกันใน Ruby แล้ว เหตุใดจึงมีอยู่และวิธีใช้งาน!
ฉันหวังว่าคุณจะพบว่าสิ่งนี้มีประโยชน์ 🙂
หากคุณชอบบทความนี้ คุณจะชอบหนังสือของฉันอย่าง Ruby Deep Dive ลองดูสิ