IT박스

람다를 블록으로 전달

itboxs 2020. 12. 25. 09:05
반응형

람다를 블록으로 전달


여러 범위의 각 방법을 전달하는 데 사용할 블록을 정의하려고합니다. 각 범위에서 블록을 재정의하는 대신 람 바를 만들고 람다를 다음과 같이 전달하고 싶습니다.

count = 0
procedure = lambda {|v| map[count+=1]=v}
("A".."K").each procedure
("M".."N").each procedure
("P".."Z").each procedure

그러나 다음과 같은 오류가 발생합니다.

ArgumentError : 잘못된 인수 개수 (0은 1)
    code.rb : 23 : in`each '에서

여기서 무슨 일이 일어나고 있는지 아이디어가 있습니까?


&인수에 앰퍼샌드 ( )를 입니다. 예를 들면 다음과 같습니다.

("A".."K").each &procedure

이것은 메소드의 특수 블록 매개 변수로 전달하고 있음을 의미합니다. 그렇지 않으면 정상적인 인수로 해석됩니다.

또한 메소드 자체에서 블록 매개 변수를 캡처하고 액세스하는 방식을 미러링합니다.

# the & here signifies that the special block parameter should be captured
# into the variable `procedure`
def some_func(foo, bar, &procedure)
  procedure.call(foo, bar)
end

some_func(2, 3) {|a, b| a * b }
=> 6

요령은 &루비에게 Proc필요한 경우이 인수를로 변환 한 다음 객체를 메서드의 블록으로 사용하도록 지시하는를 사용하는 것입니다. Ruby 1.9부터 람다 (익명) 함수에 대한 단축키가 있습니다. 따라서 다음과 같은 코드를 작성할 수 있습니다.

(1..5).map &->(x){ x*x }
# => [1, 4, 9, 16, 25]

배열의 각 요소를 가져 와서 그 힘을 계산합니다.

이 코드와 동일합니다.

func = ->(x) { x*x }
(1..5).map &func

Ruby 1.8의 경우 :

(1..5).map &lambda {|x| x*x}
# => [1, 4, 9, 16, 25]

문제를 해결하려면 Array의 방법을 사용할 수 있습니다 reduce( 0초기 값임).

('A'..'K').reduce(0) { |sum,elem| sum + elem.size }
# => 11

람다 함수를 전달하는 reduce것은 약간 까다 롭지 만 익명 블록은 람다와 거의 동일합니다.

('A'..'K').reduce(0) { |sum, elem| ->(sum){ sum + 1}.call(sum) }
# => 11

또는 다음과 같이 문자를 연결할 수 있습니다.

('A'..'K').reduce(:+)
=> "ABCDEFGHIJK"

소문자로 변환 :

('A'..'K').map &->(a){ a.downcase }
=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k"]

메서드 정의의 맥락에서 마지막 매개 변수 앞에 앰퍼샌드를 두는 것은 메서드가 블록을 취할 수 있음을 나타내며 메서드 본문 내에서이 블록을 참조하는 이름을 제공합니다.


다른 답변은 내가 확장하고 싶은 명확하지 않은 것을 남겼습니다. 메소드에 인수와 블록을 어떻게 전달합니까?

인수와 블록을받는 메서드가 있다고 가정 해 보겠습니다.

def method_with_arg_and_block(arg)
  puts arg
  yield
end

및 proc :

pr = proc { puts 'This is a proc'}

답 : proc을 메서드에 추가하는 것보다 앰퍼샌드를 사용하여 인수로 proc을 전달하는 것이 중요합니다 (블록에서 수행하는 것처럼).

예를 들어 다음과 같은 경우 :

method_with_arg_and_block('my arg') &pr

"No block given (yield)"예외가 발생합니다.

이것을 호출하는 올바른 방법은 다음과 같습니다.

method_with_arg_and_block('my arg', &pr)

Ruby는 proc을 블록으로 변환하고이를 메서드에 추가합니다. 참고 : 람다도 procs이므로 람다에서도 작동합니다.

Thanks to https://medium.com/@sihui/proc-code-block-conversion-and-ampersand-in-ruby-35cf524eef55 for helping me understand this.

ReferenceURL : https://stackoverflow.com/questions/8162257/passing-a-lambda-as-a-block

반응형