Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

วิธีใช้วิธีการแปลงทับทิม (to_s, to_a, to_str)

คุณกำลังทำงานกับจำนวนเต็ม แต่คุณต้องการใช้วิธีสตริง (เช่น 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 ลองดูสิ