คุณอาจเคยเห็นรูปแบบนี้มาก่อน เมธอดมี 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]
.
… แน่นอนว่าตอนนี้เรากลับมาที่ตัวเลือกแฮชแล้ว
อาร์กิวเมนต์คำหลักนั้นยอดเยี่ยมสำหรับการลบต้นแบบการแยกพารามิเตอร์จำนวนมากออกจากโค้ดของคุณ และคุณอาจไม่ต้องเปลี่ยนรหัสใดๆ เพื่อใช้ประโยชน์จากมัน
แต่เมื่อคุณเขียนวิธีการทั่วไปมากขึ้น มีเทคนิคใหม่ๆ บางอย่างที่คุณจะต้องเรียนรู้ที่จะจัดการกับอาร์กิวเมนต์ของคำหลักให้ดี คุณอาจไม่จำเป็นต้องใช้เทคนิคเหล่านี้บ่อยนัก แต่เมื่อคุณทำเช่นนั้น พลังและความยืดหยุ่นนี้จะรอคุณอยู่