require_relative 'person' class StudentShort < Person attr_reader :surname_initials, :contact def initialize(student) # Проверяем наличие необходимых методов и данных у student raise ArgumentError, "Объект student не имеет метод id" unless student.respond_to?(:id) raise ArgumentError, "Объект student не имеет метод git_info" unless student.respond_to?(:git_info) raise ArgumentError, "Объект student не имеет метод surname_and_initials" unless student.respond_to?(:surname_and_initials) raise ArgumentError, "Объект student не имеет метод contact_info" unless student.respond_to?(:contact_info) super(id: student.id, git: student.git_info) @surname_initials = student.surname_and_initials raise ArgumentError, "Поле surname_initials не может быть пустым" if @surname_initials.nil? || @surname_initials.strip.empty? # Дополнительная проверка на формат имен, если требуется # Если формат @surname_initials может быть сложным (например, "Иванов И.И."), # то можно добавить отдельную проверку формата: unless valid_surname_initials?(@surname_initials) raise ArgumentError, "Некорректный формат фамилии и инициалов: #{@surname_initials}" end @contact = student.contact_info raise ArgumentError, "Контактная информация не может быть пустой" if @contact.nil? || @contact.strip.empty? end def self.from_string(id, info_string) raise ArgumentError, "info_string не может быть пустой" if info_string.nil? || info_string.strip.empty? parts = info_string.split(', ').map(&:strip) # Ожидается три части: Фамилия и инициалы, Git, Контакт unless parts.size == 3 raise ArgumentError, "Строка info_string должна содержать три части разделённые запятой: '#{info_string}'" end surname_initials = parts[0] raise ArgumentError, "Не удалось извлечь фамилию и инициалы" if surname_initials.nil? || surname_initials.empty? git_part = parts[1] raise ArgumentError, "Не удалось извлечь Git-данные" if git_part.nil? || !git_part.include?(': ') git = git_part.split(': ').last raise ArgumentError, "Некорректная строка для Git: '#{git_part}'" if git.nil? || git.empty? contact_part = parts[2] raise ArgumentError, "Не удалось извлечь контактные данные" if contact_part.nil? || !contact_part.include?(': ') contact = contact_part.split(': ').last raise ArgumentError, "Некорректная строка для контакта: '#{contact_part}'" if contact.nil? || contact.empty? new_instance = allocate new_instance.send(:initialize_from_data, id, surname_initials, git, contact) new_instance end private def initialize_from_data(id, surname_initials, git, contact) raise ArgumentError, "ID должен быть числом" if id && !id.is_a?(Integer) @id = id @surname_initials = surname_initials raise ArgumentError, "Поле surname_initials не может быть пустым" if @surname_initials.nil? || @surname_initials.strip.empty? unless valid_surname_initials?(@surname_initials) raise ArgumentError, "Некорректный формат фамилии и инициалов: #{@surname_initials}" end @git = git raise ArgumentError, "Git ссылка не может быть пустой" if @git.nil? || @git.strip.empty? raise ArgumentError, "Некорректная ссылка на GitHub: #{@git}" unless self.class.valid_git?(@git) @contact = contact raise ArgumentError, "Контактная информация не может быть пустой" if @contact.nil? || @contact.strip.empty? # Инициализация родительского класса для валидации полей # Если необходимо, можно повторно вызвать super или же доверять валидации из Person при отдельном создании # В данном случае super уже вызывается в инициализаторе, а тут мы лишь готовим данные. end def valid_surname_initials?(string) # Пример простой проверки: фамилия и инициалы могут содержать буквы и точки. # Формат: "Иванов И.И." или "Petrov P.P." # Условно: первая часть - фамилия, затем инициалы через пробел. # Можно настроить по необходимости. string.match?(/\A[А-Яа-яЁёA-Za-z]+(\s+[А-Яа-яЁёA-Za-z]\.[А-Яа-яЁёA-Za-z]\.)?\z/) end end