Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

블록, 프로세서 및 람다에 대한 궁극적인 가이드

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의 차이점을 배웠고 블록을 생성할 때마다 발생하는 "닫힘" 효과에 대해서도 배웠습니다.

제가 다루지 않은 한 가지는 카레 방식입니다.

이 방법을 사용하면 필수 인수의 일부 또는 전체를 전달할 수 있습니다.

일부 인수만 전달하면 이러한 인수가 이미 '사전 로드'된 새 프로시저를 얻게 되며 모든 인수가 제공되면 프로시저가 실행됩니다.

이 게시물이 도움이 되었기를 바랍니다!

아래 양식을 구독하고 친구와 공유하는 것을 잊지 마세요. 🙂