Прекратить инициализацию объекта ruby

Какова лучшая практика, чтобы не сохранять объект, потому что не проходит определенные проверки?

Я сделал этот класс:

class Articles
  attr_reader :doi, :title, :issn

  def initialize data, doi_validator: Validators::Doi.new, title_validator: Validators::Title.new, issn_validator: Validators::Issn.new
    @doi, @title, @issn = data

    @doi_validator   = doi_validator
    @title_validator = title_validator
    @issn_validator  = issn_validator

    raise_error unless valid?
  end

  private

  def valid?
    (
      doi_validator.call(doi) && 
      title_validator.call(title) && 
      issn_validator.call(issn)
    )
  end

  attr_reader :doi_validator, :title_validator, :issn_validator
end

Дело в том, что вместо того, чтобы выдавать ошибку, я бы хотел, чтобы процесс создания экземпляров был остановлен без ущерба для потока приложения.

Вероятно, лучший способ это проверить перед инициализацией экземпляра, но это сильно усложнит приложение. Есть ли способ, который вы рекомендуете?

1 ответ

Если у вас есть что-то вроде

article = Articles.new(data)

тогда есть только две возможности:

  • Возникает исключение; article = назначение не происходит. Вам нужно поймать исключение.
  • исключение не возникает; article теперь содержит Article объект (возможно, недействительный).

Вы можете пройти середину и создать новый метод класса:

class Article
  def self.new_if_valid(*args)
    self.new(*args)
  rescue InitializationInvalidError
    nil
  end
end
class InitializationInvalidError < StandardError; end

РЕДАКТИРОВАТЬ: На самом деле, вы могли бы даже сделать это миксин, это достаточно общий:

module NilIfInitializationFails
  def self.new_if_valid(*args)
    self.new(*args)
  rescue InitializationInvalidError
    nil
  end
end
class InitializationInvalidError < StandardError; end

class Article
  include NilIfInitializationFails
  # ....
end
Другие вопросы по тегам