2009-09-06 5 views

답변

96

은 로컬 변수이며, &block은 메소드에 전달 된 블록에 대한 참조입니다. 방법에 블록으로 발동를 전달하는 방법을 호출 할 때 당신은 당신이 블록을 사용하는 것처럼 발동을 사용할 수 있도록

def foo(block = nil) 
    p block 
end 

foo # => nil 
foo("test") # => test 
foo { puts "this block will not be called" } # => nil 

def foo(&block) 
    p block 
end 

foo # => nil 
foo("test") # => ArgumentError: wrong number of arguments (1 for 0) 
foo { puts "This block won't get called, but you'll se it referenced as a proc." } 
# => #<Proc:[email protected]:20> 

또한, &block를 사용할 수 있습니다.

my_proc = proc {|i| i.upcase } 

p ["foo", "bar", "baz"].map(&my_proc) 
# => ["FOO", "BAR", "BAZ"] 

p ["foo", "bar", "baz"].map(my_proc) 
# => ArgumentError: wrong number of arguments (1 for 0) 

변수 이름 block은 특별한 것을 의미하지 않습니다. 원하는 경우 &strawberries을 사용할 수 있습니다. 여기서 앰퍼샌드가 핵심입니다.

this article이 도움이 될 수 있습니다.

+28

+1과'''& strawberries''는 – raycchan

+1

입니다. 배열에 splat (즉 '*') 연산자를 사용하는 것과 비슷합니다 : def foo (* args) ; other_foo (* args); end'는 임의의 인수 배열을 취해 그 같은 배열을 내부 함수 호출에 전달합니다. 블록을 사용하면'def foo (& block); other_foo (& 블록); 끝 ' –

27

인수 목록에서 &whatever은 메서드에 전달 된 블록을 가져 와서 Proc 개체로 래핑합니다. Proc는 whatever이라는 변수에 저장됩니다. 여기에 앰퍼샌드 뒤에 입력 한 이름 (일반적으로 "블록")이 될 수 있습니다. 메서드 호출 후 &whatever 구문은 Proc를 블록으로 변환합니다. 그래서 당신과 같이하는 방법을 정의하는 경우 : 당신은 그 블록에 다른 방법을 호출 한 후 블록을 소요하는 방법을 정의하고

def thing(&block) 
    thing2 &block 
end 

.

16

블록 전에 &을 설정하지 않으면 Ruby는 함수에 전달한 "블록"과의 관계를 인식하지 못합니다. 여기에 몇 가지 예가 나와 있습니다. 함수에서 나중에 사용하기 위해

def f(x, block); end 
f(3) { 2+2 } # gives an error, because "block" is a 
       # regular second argument (which is missing) 

def g(x, &block); end 
g(3) { 2+2 } # legal 

def h(x); end 
h(3) { 2+2 } # legal 

:

def x(&block) # x is a 0 param function 
    y(block)  # y is a 1 param function (taking one "Proc") 
    z(&block)  # z is a 0 param function (like x) with the block x received 
end 

당신이 z(&block)를 호출한다면, 그것의 (거의!) z { yield }를 호출하는 것과 같은 : 당신은 그냥 다음 기능 블록을 전달합니다.

관련 문제