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

9 คุณสมบัติใหม่ใน Ruby 2.4

มันได้กลายเป็นประเพณีในการเปิดตัว Ruby เวอร์ชันใหม่ในช่วงคริสต์มาส

และในโพสต์นี้ ฉันต้องการกล่าวถึงการเปลี่ยนแปลงที่น่าสนใจที่สุดใน Ruby 2.4 เพื่อให้คุณสามารถติดตามข่าวสารได้ 🙂

ลอย#รอบด้วยคำหลัก

หากคุณกำลังใช้ floats ในแอปของคุณ ฉันหวังว่าคุณจะใช้ floor หรือ ceil สำหรับการปัดเศษ เนื่องจากวิธี Float#round กำลังเปลี่ยนการทำงานเริ่มต้นใน Ruby 2.4

ตัวอย่าง :

# Ruby 2.3
(2.5).round
3

# Ruby 2.4
(2.5).round
2

พฤติกรรมเริ่มต้นคือตอนนี้เป็น “ปัดเศษไปใกล้สุด-คู่”

อัปเดต :ลักษณะการทำงานเริ่มต้นสำหรับ Float#round กลับมาสู่ “การปัดเศษ” ในเวอร์ชันสุดท้ายของ Ruby 2.4 . นี่เป็นการตัดสินใจของ Matz หลังจากที่โพสต์นี้เผยแพร่ครั้งแรก

นอกจากนี้ Float#round ตอนนี้รับอาร์กิวเมนต์ซึ่งคุณสามารถใช้กำหนดประเภทของการปัดเศษที่คุณต้องการได้

ตัวเลือกคือ:

  • :คู่
  • :ขึ้น
  • :ลง

ตัวอย่าง :

(4.5).round(half: :up)
5

นอกจากนี้ Float#floor , Float#ceil &Float#truncate ตอนนี้ใช้อาร์กิวเมนต์เสริมที่ให้คุณตั้งค่าความแม่นยำได้

ตั้งค่าสถานะ Chomp สำหรับวิธี IO

หากคุณเคยใช้วิธีเช่น gets หรือ each_line ฉันแน่ใจว่าคุณจำต้องรับมือกับอักขระขึ้นบรรทัดใหม่ที่น่ารำคาญ

ตัวที่มีลักษณะดังนี้:\n .

นี่คือสิ่งที่มือใหม่มักมีปัญหา แต่ฟีเจอร์ใหม่นี้อาจช่วยได้!

นี่คือตัวอย่าง:

input = gets.chomp
# "abc\n"

ตอนนี้ใน Ruby 2.4 คุณจะสามารถตั้งค่า chomp อาร์กิวเมนต์คำหลัก &gets จะลบอักขระขึ้นบรรทัดใหม่ให้คุณ

ตัวอย่าง :

input = gets(chomp: true)
# "abc"

ซึ่งจะใช้ได้กับค่าใดๆ ที่ไม่ใช่ false หรือ nil (ค่า "เท็จ" เท่านั้นใน Ruby)

ดังนั้นสิ่งนี้ก็ใช้ได้เช่นกัน (แต่ไม่แนะนำเพราะอาจทำให้สับสนได้):

input = gets(chomp: 1234)
# "abc"

ไม่ใช่เรื่องใหญ่ แต่สามารถช่วยให้คุณประหยัดการเรียกใช้เมธอดได้ 🙂

Pathname#empty?

Ruby 2.4 ใช้ Dir#empty? &File#empty? วิธีเหล่านี้ช่วยให้คุณตรวจสอบว่าไดเร็กทอรีหรือไฟล์ว่างหรือไม่ (ซึ่งค่อนข้างชัดเจนใช่ไหม)

แต่ Pathname#empty? ถูกเพิ่มเข้ามาเมื่อเร็ว ๆ นี้ด้วย

ในกรณีที่คุณไม่คุ้นเคยกับ Pathname เป็นคลาสที่ผสานการทำงานจากทั้ง Dir คลาส &File ชั้นเรียน

นอกจากนี้ยังเป็น “OO” (Object Oriented) มากกว่าในแง่ที่ส่งคืน Pathname วัตถุ แทนที่จะเป็นสตริง

ตัวอย่าง :

Pathname.empty?("file or directory name")

คอมมิต:https://github.com/ruby/ruby/commit/9373c5efb993dd8cae0526118805449b19af2c22

ตั้งค่า Compare_by_identity

ชุดเป็นโครงสร้างข้อมูลที่พร้อมใช้งานเป็นส่วนหนึ่งของไลบรารีมาตรฐาน ช่วยให้คุณเก็บสะสมไอเทมพิเศษต่างๆ ได้

โดยค่าเริ่มต้น ออบเจ็กต์จะถูกเปรียบเทียบตามค่าของออบเจ็กต์ (หรือเพื่อให้แม่นยำยิ่งขึ้น โดยอิงตามค่าแฮช)

แต่ใน Ruby 2.4 เป็นไปได้ที่จะมีชุดของอ็อบเจ็กต์ที่ไม่ซ้ำกันตาม ID อ็อบเจ็กต์ของพวกมัน

ตัวอย่าง :

require 'set'

# Normal set

set = Set.new

set << 123 << 123 << "abc" << "abc"
# [123, "abc"]

# Identity set

set = Set.new().compare_by_identity

set << 123 << 123 << "abc" << "abc"
# [123, "abc", "abc"]

หากใครทราบการใช้งานที่น่าสนใจสำหรับคุณสมบัตินี้แสดงความคิดเห็น🙂

คอมมิต:https://github.com/ruby/ruby/commit/76977611dd68e384fdce8c546efda5e1931e67a6

การปรับแต่งด้วย Kernel#send, BasicObject#send , Symbol#to_proc

ฉันจะไม่กล่าวถึงรายละเอียดการปรับแต่งที่นี่ แต่แนวคิดพื้นฐานคือการเพิ่มเมธอดให้กับคลาส เช่น String โดยคงการเปลี่ยนแปลงนี้ "แปลเป็นภาษาท้องถิ่น" เป็นไฟล์หรือคลาสเดียว

ตั้งแต่ Ruby 2.4 เมธอดที่กำหนดผ่านการปรับแต่งจะสามารถใช้ได้เมื่อเรียกผ่านเมธอดเช่น Kernel#send &Symbol#to_proc .

ตัวอย่าง :

module TenTimes
  refine String do
    def ten_times
      puts self * 10
    end
  end
end

class Thing
  using TenTimes

  "abc".send(:ten_times)
end

หากคุณลองใช้เวอร์ชัน 2.3 หรือต่ำกว่านี้ คุณจะได้รับข้อผิดพลาด 'undefined method'

คอมมิต:https://github.com/ruby/ruby/commit/35a29390197750abf97ef16fa0740e377764daef

แฮช#transform_values

นี่เป็นอีกวิธีหนึ่งที่แยกจาก Rails &มาที่ Ruby โดยตรง ฉันกำลังพูดถึง Hash#transform_values ซึ่งทำงานในลักษณะเดียวกับ Array#map .

ตัวอย่าง :

h = {a: 1, b: 2, c: 3}

h.transform_values { |v| v * 10 }
# {a: 10, b: 20, c: 30}

นอกจากนี้ยังมี Hash#transform_values! หากคุณต้องการการกลายพันธุ์แบบแทนที่

เคอร์เนล#โคลนตอนนี้ใช้อาร์กิวเมนต์คีย์เวิร์ดที่ไม่บังคับ

อย่างที่คุณอาจทราบ คุณสามารถสร้างสำเนาของวัตถุ Ruby ได้ สิ่งนี้มีประโยชน์เพราะวัตถุ Ruby ส่วนใหญ่ไม่สามารถเปลี่ยนแปลงได้ &คุณอาจต้องการหลีกเลี่ยงการเปลี่ยนแปลงวัตถุดั้งเดิม

เรามีสองวิธีในการทำสำเนาวัตถุ:

  • โคลน
  • ซ้ำซ้อน

clone &dup มีความแตกต่างกันเล็กน้อย แต่สำหรับโพสต์นี้ สมมติว่า clone คงสถานะ "แช่แข็ง" ของวัตถุเดิมไว้ในขณะที่ dup ไม่ได้

ใหม่ใน 2.4 คือความสามารถในการเรียก clone ด้วยธง "หยุด"

ตัวอย่าง :

foo = "test".freeze
boo = foo.clone(freeze: false)

boo.frozen?
# false

ฉันไม่แน่ใจว่าส่วนขยายนี้มีประโยชน์อย่างไร แต่ใครไม่ต้องการตัวเลือกเพิ่มเติม 🙂

คอมมิต:https://github.com/ruby/ruby/commit/320ae01c5fb091eab0926c186f304a9caeda1ace

Thread.report_on_exception

คุณสมบัติอื่นที่มาพร้อมกับ 2.4 คือ Thread.report_on_exception ข้อเสนอนี้ถูกเสนอเนื่องจากข้อยกเว้นของเธรดจะไม่แสดงโดยค่าเริ่มต้น และอาจซ่อนปัญหากับโค้ดของคุณได้

ค่าเริ่มต้นคือ false แต่หากแอปของคุณใช้ Threads คุณควรลองเปิดใช้งานสิ่งนี้เมื่ออัปเกรดเป็น Ruby 2.4

ตัวอย่าง :

Thread.report_on_exception = true

t1 = Thread.new do
  puts  "In new thread"
  raise "Exception from thread"
end

sleep(1)
puts "In the main thread"

นี่จะแสดงข้อยกเว้น แต่จะไม่ทำให้โปรแกรมของคุณขัดข้อง ทางเลือกอื่นคือ Thread.abort_on_exception ซึ่งมีให้ใช้งานเสมอ

โปรดสังเกตว่าวิธีนี้มีเวอร์ชันอินสแตนซ์ด้วย ดังนั้นคุณจึงสามารถตั้งค่าตัวเลือกนี้ต่อเธรดแทนเธรดทั้งหมดได้

ผูกพัน#irb

คุณเป็นแฟนตัวยงของการใช้ binding.pry สำหรับการดีบัก? ตอนนี้เราก็มี binding.irb . แล้ว ซึ่งทำงานในลักษณะเดียวกัน

แต่เนื่องจากเป็นการรบกวน คุณจึงยังไม่ได้รับสิ่งดีๆ ทั้งหมดที่แงะให้คุณ เช่น การเน้นไวยากรณ์

ดีกว่าไม่มีอะไรเลยถ้าด้วยเหตุผลบางอย่างคุณไม่สามารถเข้าถึง pry 🙂

คอมมิต:https://github.com/ruby/ruby/commit/493e48897421d176a8faf0f0820323d79ecdf94a

บทสรุป

Ruby เวอร์ชันใหม่นี้มีฟีเจอร์ที่น่าสนใจมากมาย ดังนั้นอย่าลืมลองดูเมื่อมีให้บริการ

อย่าลืม แชร์โพสต์นี้เพื่อให้คนอื่นได้เรียนรู้ เกี่ยวกับคุณสมบัติใหม่เหล่านี้ใน Ruby 2.4!