2009-07-14 5 views
1

Ruby와 Do 블록 학습. 많은 C#에서 나는 Do를 생각 나게하는 많은 것을 보지 못했지만, VB는 With 문으로 마음에 떠올랐다. 그리고 내가 원했던 것은 C# (어쩌면 본 적이없고 결코 본 적이 없다) 일 것이다. Do와 With 두 문은 비슷하게 보입니다.Do 블록은 With 문과 동일합니까?

VB의 With 문은 Ruby의 Do 블록과 동일합니까?

편집 :

이 예를 들어, 액티브 오브젝트 TheBook를 타고, 데이터베이스 테이블에 매핑 :

TheBook.new do |book| 
book.title = "my book" 
book.writer = "some author" 
end 

가 난 그냥 그것을보고에서 얻을 것이다 무엇을 이해합니다. 나는 위의 정보를 가지고 데이터베이스에 새로운 레코드를 얻을 것임을 알고 있지만 왜 그런지 모르겠습니다. 왜 책은 TheBook이 되었습니까? 오른쪽에서 왼쪽으로 읽습니까?

답변

8

번호 루비 블록 (doend으로 구분)은 기본적으로 closures입니다. VB에서 with은 단지 변수 이름을 반복해서 입력 할 필요가 없게하는 문법적 설탕입니다.

3

동일하지 않습니다. Ruby 블록은 익명 함수 (기술적으로 클로저)이며, 전달 된 메서드에 의해 실행될 수 있습니다. 예를 들어, 조각은 100까지 짝수를 얻을 수 있습니다 :

(1..100).select do |num| 
    num % 2 == 0 
end 

select 방법은 그 숫자가 선택 기준과 일치하는지 여부를 결정하기 위해 인수로 순서대로 각각의 번호 블록을 호출합니다.

가 (일반적으로이 (1..100).select {|num| num%2 == 0}로 기록 될 것입니다 -.. 그것은 어떤 차이가없는 do 구문은 중괄호 정확히 동일하다)

+0

나는 이것에 나를 던져주는 한가지가 | num | 할 일과 같은 줄에있다. 나는 너의 것과 같은 다른 사람들이 더 이해할 수있는 것을 보았고, 좀 더 이해하기 쉬운 것들을 보았다. – johnny

+3

그것은 논쟁입니다. 'def mymethod (arg)'를 쓸 때 메서드의 인수가 같은 줄에있는 것과 같은 것으로 생각하십시오. do-syntax는 일반적으로 여러 줄짜리 블록에 사용되는 반면 중괄호는 일반적으로 이와 같은 한 줄짜리 경우에 사용됩니다. – Chuck

5

주로 많이 루비가없는 C#을 개발자가 자신을 경험이기 때문에, 나는 당신의 혼란을 이해합니다.

C# 2.0의 anonymous delegates 및 C# 3.0의 lambda expressions의 개념에 익숙하다면 훨씬 더 의미가 있습니다.

TheBook.New (book => {book.title = "my book"; book.author = "some author"}); 

본질적으로 "할"는 블록을 제공 :

루비 액티브 예제에서 표현 될 수

C# 2.0을 사용하여 익명의 대표는 다음과 같이

TheBook.New ((delegate TheBook book){ 
    book.title = "my book"; 
    book.author = "some author"; 
}); 

또는 C#에서

3.0 람다 표현식을 사용하여 함수를 인수로 사용하는 메서드가 있거나 C#에서 대리자가있을 때 실행합니다.

1

실제로 소스를보고이 방법이 수행하는 작업에 대해 조금 배울 수 있습니다. 액티브 :: 자료에서 :

def initialize(attributes = nil) 
    @attributes = attributes_from_column_definition 
    @attributes_cache = {} 
    @new_record = true 
    ensure_proper_type 
    self.attributes = attributes unless attributes.nil? 
    self.class.send(:scope, :create).each { |att,value| self.send("#{att}=", value) } if self.class.send(:scoped?, :create) 
    result = yield self if block_given? 
    callback(:after_initialize) if respond_to_without_attributes?(:after_initialize) 
    result 
end 

이 질문에 대한 관심의 라인은 result = yield self if block_given?입니다. 루비에서 yield 메쏘드는 어떤 매개 변수를 사용하여 함수에 전달 된 블록을 호출합니다 (예제에서 여러분은 doend 사이의 부분이 될 것입니다). 이 경우 블록에 제공된 매개 변수는 self입니다.블록의 특정 인스턴스는 실제로 새로 작성된 ActiveRecord 객체를 전달하기 때문에 실제로 Visual Basic에서 언급 한 with 기능을 복제합니다. 그러나 다른 답변에서 논의 된 것처럼 Ruby 블록은 그.

2

나는 그것을 이런 식으로 설명 자신의 튜토리얼에서 WhyPoignant 생각 : 파이프가 블록에 각 반복의 값을 직접처럼

|varname|입니다.

하자 당신이 파일의 각 행 읽고 싶은 말 :

file.each_line do |line| 
    puts line 
end 

file.each_line

가 당신에게 데이터를 제공을, 당신은 직접 |line|를 사용하는 블록 데이터 (여기서는 단지 puts line)

Literraly : 파일을 읽고 각 줄마다 화면에 표시합니다 (정확하게는 표준 출력)

나는 종종 다음과 같은 코드를 작성합니다 : elements.each do |element| ...