programing

루비에서 proc와 람다의 차이점은 무엇입니까?

bestprogram 2023. 6. 1. 23:04

루비에서 proc와 람다의 차이점은 무엇입니까?

그리고 당신은 언제 다른 것보다 하나를 사용할 것입니까?

한 가지 차이점은 그들이 논쟁을 다루는 방식에 있습니다.을 사용하여 proc {}그리고.Proc.new {}동니다합등. 단을 사용하면 .lambda {}전달된 인수 수를 확인하는 프로세스를 제공합니다.ri Kernel#lambda:

Proc.new에 해당하지만, Proc 개체가 호출될 때 전달되는 매개 변수 수를 확인합니다.

예:

p = Proc.new {|a, b| puts a**2+b**2 } # => #<Proc:0x3c7d28@(irb):1>
p.call 1, 2 # => 5
p.call 1 # => NoMethodError: undefined method `**' for nil:NilClass
p.call 1, 2, 3 # => 5
l = lambda {|a, b| puts a**2+b**2 } # => #<Proc:0x15016c@(irb):5 (lambda)>
l.call 1, 2 # => 5
l.call 1 # => ArgumentError: wrong number of arguments (1 for 2)
l.call 1, 2, 3 # => ArgumentError: wrong number of arguments (3 for 2)

한또이, 지이했듯적을 하면,return에서는 해당하지만 람다 내에 람서 값의 다반 을지 사만 하환용 해당는 부▁inside사 용,▁butreturn a .in proc에서 됩니다.

lambda { return :foo }.call # => :foo
return # => LocalJumpError: unexpected return
Proc.new { return :foo }.call # => LocalJumpError: unexpected return

검사이 될 수 있음)를하거나 를 사용해야 할 경우에는 동일합니다.return은 proc를 사용합니다.lambda.

프로시저와 람다의 진정한 차이는 제어 흐름 키워드와 관련이 있습니다.나는 말하는 것은return,raise,break,redo,retry기타 – 제어 단어.프로시저에 반품 명세서가 있다고 가정해 보겠습니다.proc를 호출하면 proc에서 제외될 뿐만 아니라 다음과 같은 인클로저 메서드에서도 반환됩니다.

def my_method
  puts "before proc"
  my_proc = Proc.new do
    puts "inside proc"
    return
  end
  my_proc.call
  puts "after proc"
end

my_method

shoaib@shoaib-ubuntu-vm:~/tmp$ ruby a.rb
before proc
inside proc

결승전puts그 방법에서, 우리가 우리의 proc를 부를 때부터, 결코 실행되지 않았습니다.return그 안에서 우리는 그 방법에서 벗어났습니다.그러나 proc를 람다로 변환하면 다음을 얻을 수 있습니다.

def my_method
  puts "before proc"
  my_proc = lambda do
    puts "inside proc"
    return
  end
  my_proc.call
  puts "after proc"
end

my_method
shoaib@shoaib-ubuntu-vm:~/tmp$ ruby a.rb
before proc
inside proc
after proc

람다 내의 반환은 람다 자체에서 우리를 덤프할 뿐이며 동봉 방법은 계속 실행됩니다.제어 흐름 키워드가 프로시저 내에서 처리되는 방식과 람다가 그들 사이의 주요 차이점입니다.

주요 차이점은 두 가지뿐입니다.

  • 째첫, a.lambda "는 " " " 입니다.proc하지 않다.즉, 다음을 의미합니다.lambda인수를 합니다. 에, a는 된못는잘 수 의 발 는 면 반 하 생 오 가 류 인 전 수 달proc는 예상치 하고 예치않인무수할시당다니합고하를을 할당합니다.nil실종된 모든 사람들에게.
  • 번째, 에 때, 약만두.lambda을 다시. 를 사용할 는 " " ", " " " 를 사용합니다.proc반환됩니다. 호출 방법으로 돌아가지 않고 즉시 반환됩니다.

작동 방식을 보려면 아래 코드를 확인하십시오.우리의 첫 번째 방법은 다음과 같습니다.proc 번째는 번째는을 .lambda.

def batman_ironman_proc
  victor = Proc.new { return "Batman will win!" }
  victor.call
  "Iron Man will win!"
end

puts batman_ironman_proc # prints "Batman will win!"

def batman_ironman_lambda
  victor = lambda { return "Batman will win!" }
  victor.call
  "Iron Man will win!"
end

puts batman_ironman_lambda # prints "Iron Man will win!"

은 다음을 참조하십시오.proc"배트맨이 이길 것이다!"라고 말합니다. 이는 배트맨_ironman_proc 메서드로 돌아가지 않고 바로 돌아가기 때문입니다.

우리들의lambda그러나 호출된 후 메소드로 다시 이동하므로 메소드는 평가하는 마지막 코드를 반환합니다. "아이언 맨이 이길 것입니다!"

프로세스 예제

p = Proc.new { |x| puts x*2 }
[1,2,3].each(&p)              # The '&' tells ruby to turn the proc into a block 

proc = Proc.new { puts "Hello World" }
proc.call

람다 예제

lam = lambda { |x| puts x*2 }
[1,2,3].each(&lam)

lam = lambda { puts "Hello World" }
lam.call           

Procs와 Lamdas의 차이점

Procs와 lamdas의 차이점을 살펴보기 전에 둘 다 Proc 객체라는 것을 언급하는 것이 중요합니다.

proc = Proc.new { puts "Hello world" }
lam = lambda { puts "Hello World" }

proc.class # returns 'Proc'
lam.class  # returns 'Proc'

하지만, 람다는 프로크의 다른 '맛'입니다.이 약간의 차이는 객체를 반환할 때 표시됩니다.

proc   # returns '#<Proc:0x007f96b1032d30@(irb):75>'
lam    # returns '<Proc:0x007f96b1b41938@(irb):76 (lambda)>'

람다는 인수의 수를 확인하는 반면, 프로시저는 확인하지 않습니다.

lam = lambda { |x| puts x }    # creates a lambda that takes 1 argument
lam.call(2)                    # prints out 2
lam.call                       # ArgumentError: wrong number of arguments (0 for 1)
lam.call(1,2,3)                # ArgumentError: wrong number of arguments (3 for 1)

이와 대조적으로, 프로시저는 잘못된 수의 인수가 전달되더라도 상관하지 않습니다.

proc = Proc.new { |x| puts x } # creates a proc that takes 1 argument
proc.call(2)                   # prints out 2
proc.call                      # returns nil
proc.call(1,2,3)               # prints out 1 and forgets about the extra arguments

람다와 프록스는 '반환' 키워드를 다르게 취급합니다.

람다 내부의 'return'은 람다 코드 바로 외부의 코드를 트리거합니다.

def lambda_test
  lam = lambda { return }
  lam.call
  puts "Hello world"
end

lambda_test                 # calling lambda_test prints 'Hello World'

proc 내부의 'return'은 proc가 실행 중인 메서드 외부의 코드를 트리거합니다.

def proc_test
  proc = Proc.new { return }
  proc.call
  puts "Hello world"
end

proc_test                 # calling proc_test prints nothing

그리고 당신의 다른 질문에 대답하기 위해, 어떤 것을 언제 사용해야 합니까? 저는 그가 언급한 것처럼 @jtbandes를 따를 것입니다.

따라서 대부분의 빠른 사용은 동일하지만 자동으로 엄격한 인수 검사(때로는 디버깅에도 도움이 될 수 있음)를 원하거나 반환 문을 사용하여 proc 값을 반환해야 하는 경우 람다를 사용합니다.

원래 여기에 게시됨

일반적으로 람다는 방법과 더 유사하기 때문에 프로시저보다 직관적입니다.그들은 매우 엄격합니다. 그리고 그들은 당신이 리턴을 부르면 그냥 나가죠.이러한 이유로, 많은 루비스트들은 프로시저의 특별한 기능이 필요하지 않는 한 람다를 첫 번째 선택으로 사용합니다.

Procs: 클래스의 객체Proc블록과 마찬가지로 정의된 범위에서 평가됩니다.람다:클래스 개체도 있습니다.Proc하지만 일반적인 절차와는 미묘하게 다릅니다.블록이나 프로시저와 같은 폐쇄이므로 정의된 범위에서 평가됩니다.

프로세스 만들기

a = Proc.new { |x| x 2 }

람다 생성

b = lambda { |x| x 2}

이것을 이해하는 또 다른 방법이 있습니다.

블록은 객체에 대한 메서드 호출에 연결된 코드 덩어리입니다.다음 예제에서 self는 ActionView에서 상속되는 익명 클래스의 인스턴스입니다.: 레일즈 프레임워크를 기반으로 합니다(그 자체에는 많은 도우미 모듈이 포함됨).카드는 우리가 스스로 부르는 방법입니다.메서드에 인수를 전달한 다음 항상 메서드 호출의 끝에 블록을 연결합니다.

self.card :contacts do |c|
  // a chunk of valid ruby code    
end

좋아요, 그래서 우리는 코드 덩어리를 메소드에 전달하고 있습니다.하지만 이 블록을 어떻게 활용해야 할까요?한 가지 옵션은 코드 청크를 개체로 변환하는 것입니다.Ruby는 코드 덩어리를 객체로 변환하는 세 가지 방법을 제공합니다.

# lambda
> l = lambda { |a| a + 1 }
> l.call(1)
=> 2 

# Proc.new
> l2= Proc.new { |a| a + 1 }
> l2.call(1)
=> 2 

# & as the last method argument with a local variable name
def add(&block)
end

위 메소드에서 &는 메소드에 전달된 블록을 객체로 변환하고 해당 객체를 로컬 변수 블록에 저장합니다.실제로 람다 및 Proc.new와 동작이 동일함을 보여줄 수 있습니다.

def add(&block)
  block
end

l3 = add { |a| a + 1 }
l3.call(1)
=> 2

이것은 중요합니다.블록을 메서드에 전달하고 &을 사용하여 변환하면 생성되는 객체는 Proc.new를 사용하여 변환합니다.

저는 "proc"를 옵션으로 사용하는 것을 피했습니다.Ruby 1.8이기 때문에 람다와 동일하고 Ruby 1.9에서는 Pro.new와 동일하며 모든 Ruby 버전에서는 피해야 합니다.

그러면 람다와 Proc.new의 차이가 무엇인지 묻습니다.

첫째, 매개 변수 전달의 관점에서 람다는 메서드 호출처럼 동작합니다.잘못된 수의 인수를 전달하면 예외가 발생합니다.이와 대조적으로 Proc.new는 병렬 할당처럼 동작합니다.사용되지 않는 모든 인수는 0으로 변환됩니다.

> l = lambda {|a,b| puts "#{a} + #{b}" }
 => #<Proc:0x007fbffcb47e40@(irb):19 (lambda)> 
> l.call(1)
ArgumentError: wrong number of arguments (1 for 2)

> l2 = Proc.new {|a,b| puts "#{a} + #{b}" }
=> #<Proc:0x007fbffcb261a0@(irb):21> 
> l2.call(1)
1 + 

둘째, 람다와 Proc.new는 반환 키워드를 다르게 처리합니다.Proc.new 내부에서 반환을 수행하면 실제로는 동봉 방법, 즉 주변 컨텍스트에서 반환됩니다.람다 블럭에서 반환되는 경우 블럭에서 반환되는 것이지 둘러싸는 방법은 아닙니다.기본적으로, 그것은 블록에 대한 호출에서 빠져나와 나머지 인클로저 메소드로 실행을 계속합니다.

> def add(a,b)
  l = Proc.new { return a + b}
  l.call
  puts "now exiting method"
end
> add(1,1)
=> 2  # NOTICE it never prints the message "now exiting method"

> def add(a,b)
  l = lambda { return a + b }
  l.call
  puts "now exiting method"
end
> add(1,1)
=> now exiting method  # NOTICE this time it prints the message "now exiting method"

그렇다면 왜 이런 행동 차이가 있을까요?그 이유는 Proc.new를 사용하면 메소드를 포함하는 컨텍스트 내에서 반복기를 사용하고 논리적 결론을 도출할 수 있기 때문입니다.이 예를 보십시오.

> def print(max)
  [1,2,3,4,5].each do |val|
    puts val
    return if val > max
  end
end
> print(3)
1
2
3
4

우리는 우리가 반복기 내부에서 리턴을 호출할 때, 그것이 동봉 방법에서 돌아올 것으로 예상합니다.반복자에게 전달된 블록은 Proc.new를 사용하여 객체로 변환되므로 반환을 사용하면 동봉 방법이 종료됩니다.

람다는 익명의 방법이라고 생각할 수 있습니다. 그것들은 개별 코드 블록을 하나의 방법처럼 다룰 수 있는 객체로 분리합니다.궁극적으로 람다는 변칙적인 방법으로 동작하고 Proc.new는 인라인 코드로 동작한다고 생각합니다.

루비 가이드에 대한 유용한 게시물: 블록, 프로시저람다

프로크는 현재 방법에서 반환되는 반면 람다는 람다 자체에서 반환됩니다.

프록스는 정확한 인수 수에 대해 신경 쓰지 않는 반면, 람다는 예외를 제기할 것입니다.

proc와 lambda의 차이점은 proc가 단지 인수가 차례로 바뀐 코드의 복사본인 반면, lambda는 다른 언어의 함수라는 것입니다.(반품 거부, 인수 확인)

언급URL : https://stackoverflow.com/questions/1740046/whats-the-difference-between-a-proc-and-a-lambda-in-ruby