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

วิธีน้ำตาลซินแทคติกใน Ruby

ยินดีต้อนรับสู่บทความ 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