변경 가능한 상태로 인한 메모 생성을 피하는 방법에 대한 합의가 있습니까?Ruby에서 버그를 일으키는 메모 생성을 어떻게 피하는 것이 좋습니까?
이 예에서 캐시 된 결과에는 상태가 변경되어 두 번째 호출시 잘못된 결과가 나타납니다. 내가 피하기 위해 볼 수
class Greeter
def initialize
@greeting_cache = {}
end
def expensive_greeting_calculation(formality)
case formality
when :casual then "Hi"
when :formal then "Hello"
end
end
def greeting(formality)
unless @greeting_cache.has_key?(formality)
@greeting_cache[formality] = expensive_greeting_calculation(formality)
end
@greeting_cache[formality]
end
end
def memoization_mutator
greeter = Greeter.new
first_person = "Bob"
# Mildly contrived in this case,
# but you could encounter this in more complex scenarios
puts(greeter.greeting(:casual) << " " << first_person) # => Hi Bob
second_person = "Sue"
puts(greeter.greeting(:casual) << " " << second_person) # => Hi Bob Sue
end
memoization_mutator
접근 방법이 있습니다 :
greeting
이@greeting_cache[formality]
greeting
의dup
또는clone
이@greeting_cache[formality]
의 결과를freeze
수 반환 할 수 있습니다. 그럴 경우memoization_mutator
이 문자열을 추가 할 때 예외가 발생합니다.greeting
의 결과를 사용하는 모든 코드를 검사하여 문자열이 변경되지 않도록하십시오.
최상의 접근 방식에 대한 합의가 이루어 졌습니까? (1) 또는 (2)의 성능을 저하시키는 유일한 단점은 무엇입니까? (다른 개체에 대한 참조가 있으면 개체가 완전히 작동하지 않을 수도 있습니다.)
참고 :이 문제는 메모 작성의 주 응용 프로그램에는 영향을 미치지 않습니다. Fixnum
은 불변이므로 피보나치 시퀀스는 계산되지 않습니다. 가변적 인 상태에 문제가있다. :)
스타일에 대한 간단한 설명 - || = 연산자로 인사말 방법을 단순화 할 수 있습니다. 이렇게 : def greeting (formality); @greeting_cache [형식] || = 비싼 _greeting_ 계산 (형식); end – zaius
@ zaius : 대부분의 시나리오에서 작동하지만'nil' 또는'false'가 유효한 값이면 작동하지 않습니다. –
아, 맞아. 내 잘못이야. – zaius