Add lesson-9 comments#5
Conversation
|
|
||
| class Test | ||
| extend Accessor | ||
| # почему здесь использется extend, если мы обращаемся к инстансам класса, а не к классу? |
There was a problem hiding this comment.
Именно поэтому и используется. Суть в том что extend расширяет текущий объект методами модуля. При этом не имеет значения, обычный ли это объект, или сам объект класса. Наша цель добавить методы в объект класса, поэтому используем extend.
Можно расширить поведение одного конкретного объекта среди многих:
module Telepathy
def read_thoughts
p 'The brain is reading thoughts...'
end
end
class Brain
def think
p 'The brain is thinking...'
end
end
jane = Brain.new
john = Brain.new
jane.think
john.think
jane.extend(Telepathy)
jane.read_thoughts
john.read_thoughts # => NoMethodError|
|
||
| class_eval %Q{ | ||
| def #{name}=(value) | ||
| @#{name}_history = [@#{name}] unless defined? @#{name}_history |
There was a problem hiding this comment.
Можно здесь определить @#{name}_history = [] unless defined? @#{name}_history и тогда ниже проверку unless можно будет убрать.
| define_method(name) {instance_variable_get(var_name)} | ||
| define_method("#{name}=".to_sym) do |value| | ||
| raise "Argument isn't #{type} type." unless value.instance_of?(type) | ||
| instance_variable_set(var_name, value) if value.instance_of?(type) |
There was a problem hiding this comment.
Если случится raise, до этого места интерпретатор не дойдёт, поэтому условие избыточно.
| @@ -0,0 +1,12 @@ | |||
| module Validation | |||
There was a problem hiding this comment.
Лучше определить отдельный каталог modules и в нём уже хранить файл validation.rb.
| def validate(atr_name, valid_type, params = nil) | ||
| case valid_type | ||
| when :presence | ||
| define_method(:validate!) {raise "#{instance_variable_get("@#{atr_name}")} couldn't be nil" if instance_variable_get("@#{atr_name}").nil? || instance_variable_get("@#{atr_name}").empty?; true} |
There was a problem hiding this comment.
Тут суть в том чтобы как раз в одном месте определить один раз метод конкретной валидации и затем вызывать его где нужно. У нас же сейчас получается своего рода билдер, который добавляет методы валидаций физически в каждый класс.
There was a problem hiding this comment.
Также, будет много удобней определить отдельный метод валидаций один раз в этом модуле:
module Validation
private
def validate_presence
end
def validate_format
end
end| @@ -0,0 +1,9 @@ | |||
| module Valid | |||
| def valid? | |||
| if validate! | |||
There was a problem hiding this comment.
Если объект содержит ошибку то метод validate! выбросит исключение, а значит метод valid? не вернёт false. Вместо этого Ruby процесс прервёт своё выполнение с ошибкой.
| @@ -0,0 +1,9 @@ | |||
| module Valid | |||
There was a problem hiding this comment.
Также идея модуля Validations в том чтобы всю логику, которая относится к валидациям собрать в этом модуле, включае метод класса validate и остальные инстанс-методы. Пожалуйста, перечитай ещё раз задание.
No description provided.