Tak jak w temacie. Czy istnieje jakiś taki odpowiednik, który uruchomi się przed zniszczeniem obiektu? Mianowicie jeden z obiektów powinien posprzątać po sobie na dysku przed zniszczeniem i nie ma możliwości aby zrobić to z zewnątrz i przydałby się właśnie odpowiednik destruktora.
Generalnie tak. W praktyce napisanie dobrego finalizera jest dosyć trudne (zaakceptowana odpowiedź na stackoverflow nie ma prawa działać ).
Moment w którym potrzebujesz finalizera do czyszczenia po sobie na dysku to moment w którym powinieneś mocno zastanowić się jak naprawić architekturę aplikacji żeby to nie było niezbędne.
Języki z GC są takie sobie, jeśli chodzi o deterministyczność wywoływania destruktora, a Ruby, jak napisano wyżej, nie posiada nawet takiego ułomnego mechanizmu. Dla przykładu w C# stosuje się instrukcję using:
using (var res = GetResource())
{
...
}
, której odpowiednikiem funkcjonalnym, a jednocześnie dobrze znanym wzorcem Rubiego jest:
get_resource do |res|
res.foo
res.bar
end
gdzie res jest samym zasobem lub obiektem go opakowującym. Najważniejsze, że to w metodzie get_resource następuje przydzielenie oraz zwolnienie zasobów.
Moment w którym potrzebujesz finalizera do czyszczenia po sobie na dysku to moment w którym powinieneś mocno zastanowić się jak naprawić architekturę aplikacji żeby to nie było niezbędne.
Domyślam się, ale inaczej nie da rady. Nazwa klasy jest jednym z parametrów funkcji wykorzystywanej bardzo głęboko, a decyzja jaka to klasa jest podejmowana bardzo wcześnie i nijak przesyłać obiekt ponieważ informacja o tym jaki to obiekt jest łatwo uchwytna, ale już jej parametry są zależne od innych obiektów. Niestety nie ja projektowałem aplikację a człowiek uparł się na Ruby jakby to było lekarstwo na wszystko.
Spróbuję też proponowane przez Jacka domknięcia.
Poniższy kod działa tak jak tego oczekuję. Dziękuję bardzo.
#!/usr/bin/ruby
class My
def initialize
@a = 13
ObjectSpace.define_finalizer(self, self.method(:finalize))
end
def finalize(object_id)
print @a
end
end
My.new