Odpowiednik finalize z Javy lub odpowiednik destruktora[SOLVED]

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ć :slight_smile: ).

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