Có sự đồng thuận về cách tránh việc ghi nhớ gây ra lỗi do trạng thái có thể thay đổi không?Làm cách nào để tránh ghi nhớ gây ra lỗi trong Ruby?
Trong ví dụ này, kết quả được lưu trong bộ nhớ cache bị biến đổi trạng thái, và do đó cho kết quả sai lần thứ hai được gọi.
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
phương pháp tiếp cận tôi có thể nhìn thấy để tránh điều này là:
greeting
có thể trở lại mộtdup
hoặcclone
của@greeting_cache[formality]
greeting
thểfreeze
kết quả của@greeting_cache[formality]
. Điều đó sẽ gây ra một ngoại lệ được nêu ra khimemoization_mutator
nối thêm chuỗi vào đó.- Kiểm tra tất cả mã sử dụng kết quả của
greeting
để đảm bảo không có mã nào làm bất kỳ đột biến nào của chuỗi.
Có sự nhất trí nào về cách tiếp cận tốt nhất không? Là bất lợi duy nhất của làm (1) hoặc (2) giảm hiệu suất? (Tôi cũng nghi ngờ đóng băng một đối tượng có thể không hoạt động đầy đủ nếu nó có tham chiếu đến các đối tượng khác)
Lưu ý phụ: vấn đề này không ảnh hưởng đến ứng dụng chính của việc ghi nhớ: như là không thay đổi, tính chuỗi Fibonacci không có vấn đề với trạng thái có thể thay đổi. :)
Nhận xét nhỏ về kiểu - bạn có thể đơn giản hóa phương thức chào bằng toán tử || =. Như thế này: def greeting (formality); @greeting_cache [formality] || = expensive_greeting_calculation (hình thức); end – zaius
@zaius: Nó hoạt động trong hầu hết các trường hợp, nhưng sẽ không hoạt động nếu 'nil' hoặc' false' là giá trị hợp lệ. –
Ah, đúng vậy. Lỗi của tôi. – zaius