ยินดีต้อนรับสู่บทความ Ruby Magic ใหม่! ในตอนนี้ เราจะมาดูกันว่า Ruby ใช้ น้ำตาลสังเคราะห์ . อย่างไร เพื่อทำให้ไวยากรณ์บางส่วนมีความหมายมากขึ้น หรืออ่านง่ายขึ้น ในตอนท้าย เราจะรู้ว่ากลอุบายบางอย่างของ Ruby ทำงานอย่างไรภายใต้ประทุนและเขียนวิธีการของเราเองโดยใช้น้ำตาลเพียงเล็กน้อย
เมื่อเขียนแอป Ruby เป็นเรื่องปกติที่จะโต้ตอบกับแอตทริบิวต์ของคลาส อาร์เรย์ และแฮชในลักษณะที่อาจรู้สึกว่าไม่ได้มาตรฐาน เราจะกำหนดวิธีการกำหนดแอตทริบิวต์และดึงค่าจากอาร์เรย์หรือแฮชอย่างไร
Ruby ให้น้ำตาลซินแทคติกเล็กน้อยเพื่อให้วิธีการเหล่านี้ใช้ได้ผลเมื่อเรียกใช้ ในโพสต์นี้ เราจะมาศึกษาวิธีการทำงาน
person1 = Person.new
person1.name = "John"
array = [:foo, :bar]
array[1] # => :bar
hash = { :key => :foo }
hash[:key] # => :foo
hash[:key] = :value
น้ำตาลวากยสัมพันธ์?
น้ำตาลวากยสัมพันธ์หมายถึง ✨ เวทมนตร์ ✨ Ruby ให้คุณเขียนโค้ดที่อ่านง่ายและกระชับยิ่งขึ้นในการเขียน ใน Ruby หมายถึงการละทิ้งสัญลักษณ์ การเว้นวรรค หรือการเขียนนิพจน์บางอย่างกับผู้ช่วยบางประเภท
ชื่อวิธีการ
เริ่มต้นด้วยชื่อวิธีการ ใน Ruby เราสามารถใช้อักขระและสัญลักษณ์พิเศษได้ทุกประเภทสำหรับชื่อเมธอดที่ปกติไม่รองรับในภาษาอื่น หากคุณเคยเขียนแอป Rails คุณอาจเคยเจอ save!
กระบวนการ. นี่ไม่ใช่สิ่งที่เฉพาะเจาะจงสำหรับ Rails แต่แสดงให้เห็นถึงการรองรับ !
อักขระในชื่อวิธี Ruby
เช่นเดียวกับสัญลักษณ์อื่นๆ เช่น =
, [
, ]
, ?
, %
, &
, |
, <
, >
, *
, -
, +
และ /
.
การสนับสนุนอักขระเหล่านี้หมายความว่าเราสามารถรวมอักขระเหล่านี้ไว้ในชื่อวิธีการของเราเพื่อให้ชัดเจนยิ่งขึ้นเกี่ยวกับความหมายของอักขระเหล่านี้:
- การกำหนดแอตทริบิวต์:
person.name = "foo"
- ถามคำถาม:
person.alive?
- เรียกวิธีอันตราย:
car.destroy!
- การทำให้วัตถุทำเหมือนสิ่งที่ไม่ใช่:
car[:wheels]
การกำหนดวิธีการแอตทริบิวต์
เมื่อกำหนดแอตทริบิวต์ในคลาสด้วย attr_accessor
, Ruby สร้างวิธีการอ่านและเขียนสำหรับตัวแปรอินสแตนซ์ในคลาส
class Person
attr_accessor :name
end
person = Person.new
person.name = "John"
person.name # => "John"
ภายใต้ประทุน Ruby สร้างสองวิธี:
Person#name
สำหรับการอ่านตัวแปรแอตทริบิวต์/อินสแตนซ์ในคลาสโดยใช้attr_reader
, และ;Person#name=
สำหรับเขียนตัวแปรแอตทริบิวต์/อินสแตนซ์ในชั้นเรียนโดยใช้attr_writer
.
สมมติว่าเราต้องการปรับแต่งพฤติกรรมนี้ เราจะไม่ใช้ attr_accessor
เป็นตัวช่วยและกำหนดวิธีการเอง
class AwesomePerson
def name
"Person name: #{@name}"
end
def name=(value)
@name = "Awesome #{value}"
end
end
person = AwesomePerson.new
person.name = "Jane"
person.name # => "Person name: Awesome Jane"
นิยามเมธอดสำหรับ name=
เป็นแบบเดียวกับที่คุณเขียนเมื่อเรียกใช้เมธอด person.name = "Jane"
. เราไม่ได้กำหนดช่องว่างรอบเครื่องหมายเท่ากับ =
และอย่าใส่วงเล็บเมื่อเรียกใช้เมธอด
วงเล็บเสริมและช่องว่าง
คุณอาจเคยเห็นว่าในวงเล็บทับทิมเป็นทางเลือกหลายครั้ง เมื่อส่งอาร์กิวเมนต์ไปยังเมธอด เราไม่จำเป็นต้องใส่อาร์กิวเมนต์ในวงเล็บ ()
แต่เราทำได้หากอ่านง่ายกว่า
คำสั่ง if เป็นตัวอย่างที่ดี ในหลายภาษา คุณตัดนิพจน์ที่คำสั่ง if-statement ด้วยวงเล็บ ใน Ruby สามารถละเว้นได้
puts "Hello!" if (true) # With optional parentheses
puts "Hello!" if true # Without parentheses
เช่นเดียวกับคำจำกัดความของเมธอดและนิพจน์อื่นๆ
def greeting name # Parentheses omitted
"Hello #{name}!"
end
greeting("Robin") # With parentheses
greeting "Robin" # Without parentheses
greeting"Robin" # Without parentheses and spaces
บรรทัดสุดท้ายอ่านยาก แต่ใช้งานได้ วงเล็บและช่องว่างเป็นทางเลือกแม้ในขณะที่เรียกใช้เมธอด
ระวังอย่าละเว้นวงเล็บและช่องว่างทั้งหมด สิ่งเหล่านี้ช่วยให้ Ruby เข้าใจสิ่งที่คุณหมายถึง! เมื่อสงสัย ให้ใส่อาร์กิวเมนต์ไว้ในวงเล็บ เพื่อให้คุณและ Ruby ทราบว่าอาร์กิวเมนต์ใดเป็นของเมธอดใด
รองรับวิธีการเรียกใช้เมธอดต่อไปนี้ทั้งหมด แต่โดยปกติเราจะละเว้นวงเล็บและเพิ่มช่องว่างเพื่อทำให้โค้ดอ่านง่ายขึ้นเล็กน้อย
# Previous method definition:
# def name=(value)
# @name = "Awesome #{value}"
# end
person.name = "Jane"
person.name="Jane"
person.name=("Jane") # That looks a lot like the method definition!
ตอนนี้เราได้กำหนดวิธีการอ่านและเขียนแอตทริบิวต์ที่กำหนดเองสำหรับ name
คุณลักษณะ. เราปรับแต่งพฤติกรรมได้ตามต้องการและทำการแปลงค่าโดยตรงเมื่อกำหนดแอตทริบิวต์แทนที่จะต้องใช้การเรียกกลับ
การกำหนด [ ]
วิธีการ
สิ่งต่อไปที่เราจะมาดูคือวิธีวงเล็บเหลี่ยม [ ]
ในทับทิม โดยทั่วไปจะใช้เพื่อดึงและกำหนดค่าให้กับดัชนีอาร์เรย์และคีย์แฮช
hash = { :foo => :bar, :abc => :def }
hash[:foo] # => :bar
hash[:foo] = :baz # => :baz
array = [:foo, :bar]
array[1] # => :bar
ลองดูวิธีการกำหนดวิธีการเหล่านี้ เมื่อโทร hash[:foo]
เรากำลังใช้น้ำตาลซินแทคติก Ruby เพื่อทำให้สิ่งนั้นสำเร็จ อีกวิธีในการเขียนนี้คือ:
hash = { :foo => :bar }
hash.[](:foo)
hash.[]=(:foo, :baz)
# or even:
hash.send(:[], :foo)
hash.send(:[]=, :foo, :baz)
เมื่อเทียบกับวิธีที่เราเขียนตามปกติ (hash[:foo]
และ hash[:foo] = :baz
) เราเห็นความแตกต่างบางอย่างแล้ว ในตัวอย่างแรก (hash.[](:foo)
) Ruby ย้ายอาร์กิวเมนต์แรกระหว่างวงเล็บเหลี่ยม (hash[:foo]
). เมื่อโทร hash.[]=(:foo, :baz)
อาร์กิวเมนต์ที่สองถูกส่งไปยังเมธอดเป็นค่า hash[:foo] = :baz
.
เมื่อรู้อย่างนี้แล้ว เราก็สามารถกำหนด [ ]
. ของเราเองได้ และ [ ]=
วิธีที่ Ruby จะเข้าใจ
class MyHash
def initialize
@internal_hash = {}
end
def [](key)
@internal_hash[key]
end
def []=(key, value)
@internal_hash[key] = value
end
end
ตอนนี้เรารู้แล้วว่าวิธีการเหล่านี้เป็นวิธีการ Ruby ปกติ เราก็สามารถใช้ตรรกะเดียวกันกับวิธีอื่นๆ ได้ เรายังทำให้มันทำสิ่งแปลกๆ ได้ เช่น อนุญาตหลายคีย์ใน [ ]
วิธีการ
class MyHash
def initialize
@internal_hash = { :foo => :bar, :abc => :def }
end
def [](*keys)
@internal_hash.values_at(*keys)
end
end
hash = MyHash.new
hash[:foo, :abc] # => [:bar, :def]
สร้างของคุณเอง
ตอนนี้เรารู้เพียงเล็กน้อยเกี่ยวกับน้ำตาลซินแทคติกของ Ruby แล้ว เราก็สามารถนำความรู้นี้ไปใช้สร้างวิธีการของเราเอง เช่น ตัวเขียนแบบกำหนดเอง คลาสที่คล้ายกับแฮช และอีกมากมาย
คุณอาจแปลกใจว่ามีเพชรจำนวนเท่าใดที่นิยามวิธีการ เช่น วิธีวงเล็บเหลี่ยม เพื่อทำให้บางอย่างรู้สึกเหมือนเป็นอาร์เรย์หรือแฮช ทั้งที่จริงๆ แล้วไม่ใช่ ตัวอย่างหนึ่งคือการตั้งค่าข้อความแฟลชในแอปพลิเคชัน Rails ด้วย:flash[:alert] = "An error occurred"
. ในอัญมณี AppSignal เราใช้สิ่งนี้เองใน Config
class เป็นชวเลขสำหรับดึงการกำหนดค่า
นี่เป็นการสรุปลักษณะสั้น ๆ ของเราที่น้ำตาลซินแทคติกสำหรับการกำหนดเมธอดและการเรียกใน Ruby เราชอบที่จะรู้ว่าคุณชอบบทความนี้อย่างไร หากคุณมีคำถามเกี่ยวกับบทความนี้ และต้องการอ่านเกี่ยวกับอะไรต่อไป โปรดแจ้งให้เราทราบที่ @AppSignal