이 패턴을 본 적이 있을 것입니다. 메소드에는 options
이 있습니다. 추가 매개변수를 포함하는 마지막 인수로 해시:
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")
보다? 그 주장은 동일합니다!
키워드 인수 구문을 너무 한 단계 밀어넣기
만약 하지 않았다면 하지만 새로운 해시 구문으로 전환했습니까? 모든 코드를 변환할 수 있습니다. 그러나 적어도 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를 사용하여 자체적으로 전달할 수 있는 해시를 빌드할 수 있습니다. 하지만 더 좋은 방법이 있습니다.
키워드 인수 대신 일반 인수를 사용하는 경우 *
를 사용하여 배열에서 인수를 표시할 수 있습니다. :
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]
가 있는 키워드 인수 .
... 물론, 이제 옵션 해시로 돌아갑니다.
키워드 인수는 코드에서 수많은 매개변수 추출 상용구를 제거하는 데 유용합니다. 그리고 코드를 활용하기 위해 코드를 변경할 필요가 없을 수도 있습니다.
그러나 보다 일반적인 메서드를 작성할 때 키워드 인수를 잘 처리하는 방법을 배워야 하는 몇 가지 새로운 기술이 있습니다. 이러한 기술을 자주 사용하지 않아도 됩니다. 하지만 그렇게 하면 이 힘과 유연성이 여러분을 기다리고 있을 것입니다.