Zbadałem trochę i przyniosłem rozwiązanie. Powiedziałeś, że masz moduł, w którym robisz szyfrowanie. Zgaduję, że ten moduł reprezentuje singleton. Moje rozwiązanie wymaga jednak zamiast tego instancji.
class Crypto
def self.instance
@__instance__ ||= new
end
end
Wyodrębnić zachowanie szyfrowania w module.
module Encryptable
def encrypt
# ...
end
def decrypt
# ...
end
end
Utwórz nowy moduł obsługujący wyjątki.
module ExceptionHandler
extend ActiveSupport::Concern
included do
include ActiveSupport::Rescuable
rescue_from StandardError, :with => :known_error
end
def handle_known_exceptions
yield
rescue => ex
rescue_with_handler(ex) || raise
end
def known_error(ex)
Rails.logger.error "[ExceptionHandler] Exception #{ex.class}: #{ex.message}"
end
end
Więc teraz można użyć nowo zdefiniowane handle_known_exceptions
wewnątrz Crypto
. Nie jest to bardzo wygodne, ponieważ nie zyskałeś wiele. Trzeba jeszcze zadzwonić do obsługi wyjątku wewnątrz każdej metody:
class Crypto
include ExceptionHandler
def print_bunnies
handle_known_exceptions do
File.open("bunnies")
end
end
end
Nie trzeba tego robić, jeśli definiujemy Delegator że robi to za nas:
class CryptoDelegator
include ExceptionHandler
def initialize(target)
@target = target
end
def method_missing(*args, &block)
handle_known_exceptions do
@target.send(*args, &block)
end
end
end
Całkowicie nadpisać inicjalizacji Crypto
, aby użyj zamiast tego delegata.
class Crypto
include Encryptable
def self.new(*args, &block)
CryptoDelegator.new(super)
end
def self.instance
@__instance__ ||= new
end
end
I to wszystko!
czy włączasz ten moduł do kontrolera, czy nie? 'rescue_from' ma być używany tylko wewnątrz kontrolerów, więc robienie czegoś takiego w zwykłych starych obiektach z rubinem zawierałoby bardzo brudne hacki. – shime
Ah, rozumiem. Dzięki @shime – Matt
Chętnie pomogę. Sprawdź tutaj, jeśli chcesz wiedzieć, co mam na myśli przez brudne hacki: http://www.simonecarletti.com/blog/2009/12/inside-ruby-on-rails-rescuable-and-rescue_from/ - Nie podoba mi się jak rzeczy wyglądają, gdy robisz to w Ruby i wydaje się, że dodajesz niepotrzebny bałagan. Wyodrębnianie obsługi wyjątków we własnej metodzie jest sposobem na zwiększenie pewności kodu, który wydaje się pasować najbardziej do scenariusza. Przeczytaj więcej na ten temat tutaj: http://avdi.org/talks/confident-code-railsconf-2011/ – shime