2012-10-29 8 views
7

저는 ActiveRecord 객체의 두 요소 배열 인 slots_to_import을 가지고 있습니다. 이러한 개체에는 begin_at 개의 열이 있으며 따라서 특성이 있습니다. 나는 고유 한 begin_at 값을 가진 객체를 얻으려고했습니다. 아아, slots_to_import.uniq_by(&:begin_at)가 작동하지 않았습니다. 그러나 begin_at 값은 두 개체에 대한 동일 :루비 이상 : x == y && [x, y] .uniq == [x, y]

(rdb:1) p slots_to_import.first.begin_at == slots_to_import.last.begin_at 
true 
(rdb:1) p slots_to_import.uniq_by(&:begin_at).map(&:begin_at) 
[Mon, 26 Nov 2012 19:00:00 UTC +00:00, Mon, 26 Nov 2012 19:00:00 UTC +00:00] 
(rdb:1) p [slots_to_import.first.begin_at, slots_to_import.last.begin_at].uniq 
[Mon, 26 Nov 2012 19:00:00 UTC +00:00, Mon, 26 Nov 2012 19:00:00 UTC +00:00] 

좀 더 주위를 확인 :

(rdb:1) p [slots_to_import.first.begin_at.to_datetime, slots_to_import.last.begin_at.to_datetime].uniq 
[Mon, 26 Nov 2012 19:00:00 +0000] 
(rdb:1) p [slots_to_import.first.begin_at.usec, slots_to_import.last.begin_at.usec].uniq 
[0] 
(rdb:1) p [slots_to_import.first.begin_at.to_f, slots_to_import.last.begin_at.to_f].uniq 
[1353956400.0] 
(rdb:1) p [slots_to_import.first.begin_at.utc, slots_to_import.last.begin_at.utc].uniq 
[Mon, 26 Nov 2012 19:00:00 +0000] 
(rdb:1) p [slots_to_import.first.begin_at, slots_to_import.last.begin_at].uniq 
[Mon, 26 Nov 2012 19:00:00 UTC +00:00, Mon, 26 Nov 2012 19:00:00 UTC +00:00] 

나는 (그들이 아니었다 때문에) 아마도 그 UNIQ 그들이 같은 객체가 있었다 여부를 확인 생각했다.

1.8.7 :111 > x = Time.zone.parse("Mon, 29 Oct 2012 19:29:17 UTC +00:00") 
=> Mon, 29 Oct 2012 19:29:17 UTC +00:00 
1.8.7 :112 > y = Time.zone.parse("Mon, 29 Oct 2012 19:29:17 UTC +00:00") 
=> Mon, 29 Oct 2012 19:29:17 UTC +00:00 
1.8.7 :113 > x == y 
=> true 
1.8.7 :114 > [x, y].uniq 
=> [Mon, 29 Oct 2012 19:29:17 UTC +00:00] 

내가 루비 1.8.7p358 및 ActiveSupport 3.2.0을 사용하고 있습니다 :하지만, 내 레일 콘솔의 일부 noodling는 오브젝트 ID 검사를 사용하지 않는 것을 나에게 보여 주었다. BTW, 난 그냥 to_datetime 추가하여 내 자신의 문제를 해결할 수 있지만 정말 변환이 작동하지 않는 이유는 궁금 해서요.

+4

'x.hash'와'y.hash'의 결과를 비교해 보았습니까? – hammar

+0

@hammar : 'uniq_by'가 Hash 기반이라는 것을 보는 흥미로운 아이디어입니다. –

+0

@hammar'x.hash'와'y.hash'도 같습니다! -'(rdb : 1) p slots_to_import.first.begin_at.hash == slots_to_import.last.begin_at.hash => true' – ehsanul

답변

0

다른 마이크로 초는 제 추측입니다. 2 개체는 동일한 검사 문자열을 표시 할 수 있지만 같지는 않습니다.

+0

검사 문자열은 맞지만 마이크로 초 정도는 틀립니다. 당신은 내 질문에'usec' 메쏘드로 확인한다는 것에 주목할 것입니다. 인용구 :'(rdb : 1) p [slots_to_import.first.begin_at.usec, slots_to_import.last.begin_at.usec] .uniq => [0]' – ehsanul

+0

또한, 나는 다른 마이크로 초를 가진 두 datetimes/times를 생각하지 않는다. 서로에게 === 1.8.7 : 006 Time.now == Time.now => false' – ehsanul

0
irb(main):017:0> x = 'a' 
=> "a" 
irb(main):018:0> y = 'a' 
=> "a" 
irb(main):019:0> x == y 
=> true 
irb(main):020:0> [x,y].uniq 
=> ["a"] 
irb(main):021:0> x.object_id == y.object_id 
=> false 
irb(main):024:0> x.hash == y.hash 
=> true 

루비 평등 테스트는 참조가 아니라 값을 기반으로합니다. 당신은 그들이 같은 객체를 참조하는 경우 비교하려는 경우, 당신은 당신이 일반 Time 객체 작업 알았는데 o.object_id

+0

나는 가치에 대한 것이지 참조하지는 않습니다. 스 니펫에서 값은 동일하고 '유니크 (uniq)'는이를 반영합니다. 광산에서는 값이 동일하지만 유니 치는 그것을 반영하지 않습니다. – ehsanul

1

을 비교해야한다, 그래서 루비 플랫폼 소스 (1.9.3)에서 time.c보고 시작했다. 그들이 루비 1.9.3 Time 객체 인 경우에, 당신은 시도 할 수 :

[x.to_r, y.to_r] 

지금 내가 아는 당신이 ActiveSupport::TimeWithZone 개체 노력하고 있습니다. (제안으로, 당신이 질문을 게시이 다음과 같은 주요 정보를 언급하는 것이 좋을 것입니다.) 여기 ActiveSupport::TimeWithZone#eql?의 몸 :

def eql?(other) 
    utc == other 
end 

가 그리고 여기에 해시 함수입니다 :

alias :hash, :to_i 

다음 단계는 [x.utc, y.utc, x.to_i, y.to_i, x.utc.class, y.utc.class]에서 얻은 정보를 보여주는 것입니다.

+0

루비 1.8.7p358 용인가요?'Time.now.to_r'을 수행하면'NoMethodError : undefined method \'to_r''이 발생합니다. 또한,이 특별한'ActiveSupport :: TimeWithZone' 오브젝트는'to_r' 메소드가 빠진'DateTime' 오브젝트에 의해 뒷받침됩니다. – ehsanul

+0

저는 Ruby 1.9.3의 소스를보고있었습니다. 시간이 있다면 나는 Ruby 1.8 소스를 보게 될 것이다. 그 동안 대신에'to_f'를 시도해 보라. –

+0

감사합니다. 나는 이미'to_f' 수표를 찍었고 원래의 질문에 그 수표를 포함 시켰습니다. – ehsanul