2017-01-21 12 views
5

#each_with_object#inject은 모두 해시를 작성하는 데 사용할 수 있습니다. 예를 들어#each_with_object와 #inject가 블록 매개 변수의 순서를 전환하는 이유는 무엇입니까?

: 둘 사이의 주요 차이점

matrix = [['foo', 'bar'], ['cat', 'dog']] 

some_hash = matrix.inject({}) do |memo, arr| 
    memo[arr[0]] = arr 
    memo # no implicit conversion of String into Integer (TypeError) if commented out 
end 
p some_hash # {"foo"=>["foo", "bar"], "cat"=>["cat", "dog"]} 

another_hash = matrix.each_with_object({}) do |arr, memo| 
    memo[arr[0]] = arr 
end 
p another_hash # {"foo"=>["foo", "bar"], "cat"=>["cat", "dog"]} 

하나 #each_with_object는 전체 반복을 통해 memo 추적 인 반면 #inject 세트의 각 반복에서, 블록에 의해 리턴 된 값 memo 동일.

또 다른 차이점은 순서 또는 블록 매개 변수입니다.

여기에 몇 가지 의도가 전달되어 있습니까? 두 가지 유사한 방법의 블록 매개 변수를 뒤집는 것은 의미가 없습니다.

답변

4

그들은 서로 다른 조상을 가지고 있습니다.

  • each_with_object

  • inject 1980 언어가 그들이 가능성에 인수를 기대 시작에서 두 가지 방법으로 설계한다면 내 생각

다시 스몰 토크에 간다 2007 년 루비 1.9에 추가되었습니다 같은 순서. 그러나 이것이 어떻게 일어 났는지는 아닙니다. inject은 Ruby가 시작된 이래로 주변에 있었지만 each_with_object은 10 년 후에 추가되었습니다.

inject는 스몰 토크의 왼쪽 배를 수행 inject:into:

collection inject: 0 into: [ :memo :each | memo + each ] 

과 같은 순서로 인수를 기대하고있다. 컬렉션을 왼쪽에서 위로 접혀있는 긴 종이 조각으로 생각할 수 있으며 접기 기능의 슬라이딩 창은 항상 접힌 부분과 나머지 종이 조각의 다음 요소를 더한 것입니다.

# (memo = 0 and 1), 2, 3, 4 
# (memo = 1 and 2), 3, 4     
# (memo = 3 and 3), 4      
# (memo = 6 and 4)      

스몰 토크 협약에 따르면 Enumerable의 모든 초기 메서드가 스몰 토크에서 취해 졌기 때문에 Matt는 스몰 토크에 익숙한 사람들을 혼동하지 않으려했습니다.

누구도 루시 1.9에 each_with_object이 소개되었고 인수의 순서가 메서드 이름의 어순 순서 인 each ... object을 반영한다는 것을 알 수있는 선견지명이 없습니다.

따라서 두 가지 방법은 역사적인 이유로 서로 다른 순서로 인수를 기대합니다.

+0

좋은 흥미로운 이야기. [Enumerator # with_object] (http://ruby-doc.org/core-2.3.0/Enumerator.html#method-i-with_object)와 일관성이 있기를 바랍니다. 예를 들어. 'arr.each_with_index.with_object ({}) {| (e, i), h | ...'. 블록 변수'| h, (e, i) |'를 갖는 것은 매우 혼란 스러웠을 것입니다. –

+0

[Enumerable # each_with_index] (http://ruby-doc.org/core-2.3.0/Enumerable.html#method-i-each_with_index)와 [Enumerator # each_index] (블록 변수 배치에서의 일관성) http://ruby-doc.org/core-2.3.0/Enumerable.html#method-i-each_with_index)도 요인이 될 수 있습니다. –

+1

"인수의 순서는 메서드 이름의 어순 순서를 반영합니다. 각 이름은 'each ... object'입니다."........... 나는 항상 순서를 잊어 버리므로 결코 그렇게하지 않을 것입니다. –