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

สนุกกับอาร์กิวเมนต์คีย์เวิร์ด แฮช และ Splats

คุณอาจเคยเห็นรูปแบบนี้มาก่อน เมธอดมี options hash เป็นอาร์กิวเมนต์สุดท้ายซึ่งมีพารามิเตอร์พิเศษ:

def hello_message(name_parts = {})
  first_name = name_parts.fetch(:first_name)
  last_name = name_parts.fetch(:last_name)

  "Hello, #{first_name} #{last_name}"
end

ขออภัย คุณต้องแยกพารามิเตอร์เหล่านั้นออกจากแฮช และนั่นก็หมายความว่ามีฉากมากมายที่ต้องทำก่อนที่คุณจะไปถึงส่วนที่ดี

แต่หากคุณเปลี่ยนวิธีนี้เพื่อใช้อาร์กิวเมนต์คำหลักใน Ruby 2.0+ คุณจะไม่ต้องดึง :first_name และ :last_name จากแฮชของคุณ Ruby ทำเพื่อคุณ:

def hello_message(first_name:, last_name:)
  "Hello, #{first_name} #{last_name}"
end

ยิ่งไปกว่านั้น หากแอปของคุณใช้ไวยากรณ์แฮช Ruby 1.9+ เมธอดของคุณสามารถใช้อาร์กิวเมนต์ของคีย์เวิร์ดโดยไม่ต้องเปลี่ยนผู้เรียกใช้เมธอดเหล่านั้น:

def hello_message_with_an_options_hash(name_parts = {})
  first_name = name_parts.fetch(:first_name)
  last_name = name_parts.fetch(:last_name)

  "Hello, #{first_name} #{last_name}"
end

def hello_message_with_keyword_arguments(first_name:, last_name:)
  "Hello, #{first_name} #{last_name}"
end

hello_message_with_an_options_hash(first_name: "Justin", last_name: "Weiss")

hello_message_with_keyword_arguments(first_name: "Justin", last_name: "Weiss")

ดู? อาร์กิวเมนต์เหล่านั้นเหมือนกัน!

การพุชไวยากรณ์อาร์กิวเมนต์ของคีย์เวิร์ดเกินขั้นตอนเดียว

จะเกิดอะไรขึ้นถ้าคุณ ไม่มี เปลี่ยนไปใช้ไวยากรณ์ Hash ใหม่หรือไม่ คุณสามารถแปลงรหัสทั้งหมดของคุณ แต่อย่างน้อยใน Ruby 2.2.1 เก่า ไวยากรณ์แฮชทำงานได้ดีกับอาร์กิวเมนต์ของคำหลัก:

irb(main):007:0> hello_message_with_keyword_arguments(:first_name => "Justin", :last_name => "Weiss")
=> "Hello, Justin Weiss"

ดี! แล้วการส่งแฮช วัตถุ แทนที่จะโต้แย้ง?

irb(main):008:0> options = {:first_name => "Justin", :last_name => "Weiss"}
irb(main):009:0> hello_message_with_keyword_arguments(options)
=> "Hello, Justin Weiss"

โว้ว. จะเป็นอย่างไรถ้าเราต้องการ มิกซ์ อาร์กิวเมนต์แฮชและคีย์เวิร์ด?

irb(main):010:0> options = {last_name: "Weiss"}
irb(main):011:0> hello_message_with_keyword_arguments(first_name: "Justin", options)
SyntaxError: (irb):11: syntax error, unexpected ')', expecting =>
	from /usr/local/bin/irb:11:in `<main>'

ตกลง. ฉันเดาว่าเราก้าวไปหนึ่งก้าวเกินไป ในการแก้ไขปัญหานี้ คุณสามารถใช้ Hash#merge เพื่อสร้างแฮชที่คุณสามารถส่งผ่านเข้าไปได้เอง แต่มีวิธีที่ดีกว่านี้

หากคุณใช้อาร์กิวเมนต์ปกติแทนอาร์กิวเมนต์คีย์เวิร์ด คุณสามารถแสดงอาร์กิวเมนต์จาก Array โดยใช้ * :

def generate_thumbnail(name, width, height)
  # ...
end

dimensions = [240, 320]
generate_thumbnail("headshot.jpg", *dimensions)

แต่มีวิธีสาด คำหลัก อาร์กิวเมนต์ในรายการอาร์กิวเมนต์?

ปรากฎว่ามี:** . นี่คือวิธีแก้ไขตัวอย่างที่เสียหายด้วย ** :

irb(main):010:0> options = {last_name: "Weiss"}
irb(main):011:0> hello_message_with_keyword_arguments(first_name: "Justin", **options)
=> "Hello, Justin Weiss"

และถ้าคุณเป็นจริงๆ บ้าไปแล้ว คุณสามารถผสมอาร์กิวเมนต์ปกติ อาร์กิวเมนต์คีย์เวิร์ด และเครื่องหมาย:

def hello_message(greeting, time_of_day, first_name:, last_name:)
  "#{greeting} #{time_of_day}, #{first_name} #{last_name}!"
end

args = ["Morning"]
keyword_args = {last_name: "Weiss"}

hello_message("Good", *args, first_name: "Justin", **keyword_args) # => "Good Morning, Justin Weiss!"

แน่นอน หากคุณพบว่าตัวเองอยู่ในสถานการณ์ที่จำเป็น คุณอาจทำผิดพลาดก่อนหน้านี้มาก!

จับอาร์กิวเมนต์ของคีย์เวิร์ดด้วยวิธีง่ายๆ

คุณรู้หรือไม่ว่าคุณสามารถเปลี่ยนอาร์กิวเมนต์วิธีการทั้งหมดของคุณให้เป็นอาร์เรย์โดยใช้ * ?

def argument_capturing_method(*args)
  args
end

argument_capturing_method(1, 2, 3) # => [1, 2, 3]

สิ่งนี้ยังใช้ได้กับอาร์กิวเมนต์ของคำหลัก จะถูกแปลงเป็นแฮช และแสดงเป็นอาร์กิวเมนต์สุดท้ายของ args . ของคุณ อาร์เรย์:

argument_capturing_method(1, 2, 3, key: "value") # => [1, 2, 3, {:key=>"value"}]

แต่ args.last[:key] ไม่ใช่วิธีที่ดีที่สุดในการอ่านอาร์กิวเมนต์ของคีย์เวิร์ดด้วยวิธีนี้ คุณสามารถใช้ ** . ใหม่แทนได้ ไวยากรณ์เพื่อรับอาร์กิวเมนต์คำหลักด้วยตัวเอง:

def dual_argument_capturing_method(*args, **keyword_args)
  {args: args, keyword_args: keyword_args}
end

dual_argument_capturing_method(1, 2, 3, key: "value") # => {:args=>[1, 2, 3], :keyword_args=>{:key=>"value"}}

ด้วยไวยากรณ์นี้ คุณสามารถเข้าถึงอาร์กิวเมนต์ปกติตัวแรกด้วย args[0] และ :key อาร์กิวเมนต์คีย์เวิร์ดที่มี keyword_args[:key] .

… แน่นอนว่าตอนนี้เรากลับมาที่ตัวเลือกแฮชแล้ว

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

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