Ruby 블록, 프로시저 및 람다.
그들은 무엇입니까?
어떻게 작동합니까?
서로 어떻게 다른가요?
이 게시물을 읽고 더 많은 것을 배우게 될 것입니다!
내용
- 1 Ruby 블록 이해
- 2 Ruby Yield 키워드
- 3가지 암시적 블록과 명시적 블록
- 4 차단이 되었는지 확인하는 방법
- 5 람다란 무엇입니까?
- 6개의 Lambda 대 프로세서
- 7개의 폐쇄
- 8 바인딩 클래스
- 9 동영상 튜토리얼
- 10 마무리
- 10.1 관련
루비 블록 이해
Ruby 블록은 메서드에 전달할 수 있는 작은 익명 함수입니다.
블록은 do / end
로 묶입니다. 문 또는 대괄호 사이 {}
, 여러 인수를 가질 수 있습니다.
인수 이름은 두 파이프 |
사이에 정의됩니다. 문자.
each
을 사용한 경우 이전에는 블록을 사용했습니다!
예시입니다 :
# 형식 1:한 줄 블록에 권장[1, 2, 3].each { |num| puts num } ^^^^^ ^^^^^^^^ 블록 인수 본문
# 형식 2:여러 줄 블록에 권장[1, 2, 3].each do |num| 숫자를 넣다
Ruby 블록은 약간의 논리(코드)를 저장하고 나중에 사용할 수 있기 때문에 유용합니다.
이것은 파일에 데이터 쓰기, 한 요소가 다른 요소와 같은지 비교, 오류 메시지 인쇄와 같은 것일 수 있습니다.
루비 수익 키워드
yield
은 무엇입니까? Ruby는 무엇을 의미합니까?
수익은 Ruby 키워드입니다. 사용할 때 블록을 호출합니다.
USE 메소드가 차단하는 방법입니다!
yield
를 사용하는 경우 키워드, 블록 안의 코드가 실행 일을 하십시오.
일반 Ruby 메서드를 호출할 때와 같습니다.
예시 :
def print_once yieldendprint_once { puts "블록이 실행 중입니다" }
이것은 print_once
에 전달된 모든 블록을 실행합니다. , 결과적으로 "Block is being run"
화면에 인쇄됩니다.
알고 계셨나요...
해당 yield
여러 번 사용할 수 있습니까?
yield
를 호출할 때마다 , 블록이 실행되므로 동일한 메서드를 다시 호출하는 것과 같습니다.
예 :
def print_twice yield yieldendprint_twice { puts "Hello" }# "Hello# "Hello"
방법과 마찬가지로...
yield
에 원하는 수의 인수를 전달할 수 있습니다. .
예 :
def one_two_three yield 1 yield 2 yield 3endone_two_three { |number| 숫자 * 10 }# 10, 20, 30
이 인수는 블록의 인수가 됩니다.
이 예에서 number
.
암시적 블록과 명시적 블록
블록은 "명시적" 또는 "암시적"일 수 있습니다.
명시적이란 매개변수 목록에 이름을 지정한다는 의미입니다.
명시적 블록을 다른 메서드에 전달하거나 나중에 사용하기 위해 변수에 저장할 수 있습니다.
예시입니다 :
defexplicit_block(&block) block.call # yieldendexplicit_block과 동일 { puts "명시적 블록 호출" }
&block
주목 매개변수...
이것이 블록의 이름을 정의하는 방법입니다!
블록이 주어졌는지 확인하는 방법
yield
하려고 하면 블록이 없으면 no block given (yield)
이 됩니다. 오류.
block_given?
으로 블록이 전달되었는지 확인할 수 있습니다. 방법.
예 :
def do_something_with_block은 block_given이 아니면 "블록이 주어지지 않음"을 반환합니까? 양보
이렇게 하면 누군가 블록 없이 메서드를 호출하는 경우 오류를 방지할 수 있습니다.
람다란 무엇입니까?
람다는 특정 구문을 사용하여 블록 및 해당 매개변수를 정의하는 방법입니다.
나중에 사용할 수 있도록 이 람다를 변수에 저장할 수 있습니다.
Ruby 람다 정의를 위한 구문 다음과 같습니다.
say_something =-> { "이것은 람다입니다" }<블록 인용>
다음과 같은 대체 구문을 사용할 수도 있습니다. lambda
->
대신 .
람다를 정의하면 그 안의 코드가 실행되지 않습니다. 메서드를 정의하면 메서드가 실행되지 않는 것처럼 call
을 사용해야 합니다. 방법입니다.
예 :
say_something =-> { puts "이것은 람다입니다" }say_something.call# "이것은 람다입니다"
call
하는 다른 방법이 있습니다. lambda
, 그들이 존재한다는 것을 아는 것은 좋지만 call
을 계속 사용하는 것이 좋습니다. 명확성을 위해.
목록은 다음과 같습니다. :
my_lambda =-> { "Lambda 호출됨" }my_lambda.callmy_lambda.()my_lambda[]my_lambda.===
Lambda는 인수를 사용할 수도 있습니다. 예를 들면 다음과 같습니다.
times_two =->(x) { x * 2 }times_two.call(10)# 20
lambda
에 잘못된 수의 인수를 전달하는 경우 , 일반 메서드와 마찬가지로 예외가 발생합니다.
람다 대 프로세서
Proc는 매우 유사한 개념입니다...
차이점 중 하나는 생성 방법입니다.
예 :
my_proc =Proc.new { |x| x를 넣습니다 }
전용 Lambda
가 없습니다. 수업. lambda
특별한 Proc
일 뿐입니다. 물체. Proc
의 인스턴스 메소드를 살펴보면 , lambda?
가 있음을 알 수 있습니다. 방법.
지금 :
프로시저는 특히 인수와 관련하여 람다와 다르게 동작합니다.
t =Proc.new { |x,y| "나는 논쟁에 신경 쓰지 않는다!" }t.call# "논쟁은 신경 안 써!"
procs
의 또 다른 차이점 &lambda
return
에 반응하는 방식입니다. 성명서.
lambda
return
일반적으로 일반적인 방법과 같습니다.
하지만 proc
return
을 시도합니다. 현재 컨텍스트에서.
제 말은 다음과 같습니다. :
다음 코드를 실행하면 proc
LocalJumpError
발생 예외.
그 이유는 return
할 수 없기 때문입니다. 최상위 컨텍스트에서.
시도 :
# should workmy_lambda =-> { return 1 }puts "Lambda result:#{my_lambda.call}# Should 제기 exceptionmy_proc =Proc.new { return 1 }puts "Proc result:#{my_proc.call}"사전>
proc
메소드 내부에 있는 경우return
호출 해당 메서드에서 반환하는 것과 같습니다.이것은 다음 예에서 보여줍니다.
def call_proc puts "Before proc" my_proc =Proc.new { return 2 } my_proc.call puts "After proc" endp call_proc# "Before proc"을 출력하지만 "After proc"은 출력하지 않음다음은
procs
에 대한 요약입니다. 및lambda
다릅니다:
- 람다는
-> {}
로 정의됩니다.Proc.new {}
가 있는 procs . - 프로세스는 현재 메서드에서 반환되고 람다는 람다 자체에서 반환됩니다.
- 프로세스는 올바른 인수 수에 신경 쓰지 않지만 람다는 예외를 발생시킵니다.
이 목록을 보면 lambdas
procs
보다 일반 메서드에 훨씬 더 가깝습니다. 있습니다.
폐업
Ruby procs &lambdas에는 또 다른 특별한 속성이 있습니다. Ruby proc을 생성하면 현재 실행 범위를 함께 캡처합니다.
클로저라고도 하는 이 개념은 proc
정의된 컨텍스트의 로컬 변수 및 메서드와 같은 값을 포함합니다.
그것들은 실제 값을 전달하지 않고 그것들에 대한 참조를 전달하므로 proc이 생성된 후 변수가 변경되면 proc은 항상 최신 버전을 갖게 됩니다.
예시를 보자 :
def call_proc(my_proc) count =500 my_proc.callendcount =1my_proc =Proc.new { puts count }p call_proc(my_proc) # 이것은 무엇을 출력합니까?
이 예에서는 로컬 count
가 있습니다. 1
로 설정된 변수 .
my_proc
라는 proc도 있습니다. 및 call_proc
실행되는 메소드(call
를 통해 메서드) 인수로 전달된 모든 proc 또는 람다.
이 프로그램이 무엇을 인쇄할 것이라고 생각하십니까?
500
처럼 보일 것입니다. 가장 논리적인 결론이지만 '클로저' 효과로 인해 1
이 인쇄됩니다. .
이것은 proc이 count
값을 사용하기 때문에 발생합니다. proc이 정의된 곳에서, 그리고 그것은 메서드 정의 밖에 있습니다.
바인딩 클래스
Ruby procs 및 lambdas는 이 범위 정보를 어디에 저장합니까?
Binding
에 대해 알려드리겠습니다. 수업…
Binding
을 만들 때 Binding
을 통한 객체 메서드에서 코드의 이 지점에 '앵커'를 만들고 있습니다.
이 시점에서 정의된 모든 변수, 메서드 및 클래스는 완전히 다른 범위에 있더라도 나중에 이 개체를 통해 사용할 수 있습니다.
예 :
def return_binding foo =100 bindingend# Foo는 바인딩 덕분에 사용할 수 있습니다.# 비록 정의된 메서드의 외부에 있음에도##.puts return_binding.classputs return_binding.eval('foo')# foo를 직접 인쇄하면 오류가 발생합니다.# foo가 method.puts foo 외부에서 정의된 적이 없기 때문입니다.
즉, Binding
컨텍스트에서 실행 개체는 해당 코드가 해당 Binding
정의되었습니다('앵커' 은유 기억).
Binding
을 사용할 필요가 없습니다. 객체를 직접 사용하지만 이것이 사물이라는 것을 아는 것은 여전히 좋은 일입니다 🙂
동영상 튜토리얼
마무리
이 게시물에서는 블록이 어떻게 작동하는지, Ruby procs와 lambdas의 차이점을 배웠고 블록을 생성할 때마다 발생하는 "닫힘" 효과에 대해서도 배웠습니다.
제가 다루지 않은 한 가지는 카레 방식입니다.
이 방법을 사용하면 필수 인수의 일부 또는 전체를 전달할 수 있습니다.
일부 인수만 전달하면 이러한 인수가 이미 '사전 로드'된 새 프로시저를 얻게 되며 모든 인수가 제공되면 프로시저가 실행됩니다.
이 게시물이 도움이 되었기를 바랍니다!
아래 양식을 구독하고 친구와 공유하는 것을 잊지 마세요. 🙂