2008-10-13 4 views
4

Я хочу сделать некоторую проверку в ассемблере записи. Моя первая идея возвращала логическое значение.Есть ли способ для аксессуаров Ruby возвращать нечто, отличное от заданной переменной?

class MyClass 
    def var=(var) 
    @var = var 
    # some checking 
    return true 
    end 
end 

m = MyClass.new 
retval = (m.var = 'foo') 

=> "foo" 

Можно ли установить возвращаемое значение в аксессуре для записи? Если да, как я могу получить это значение?

+0

Можете ли вы привести пример какой проверки? Я немного потерял то, что вы подразумеваете под этим. Но у меня есть подозрение, что это очень возможно, просто нужно уточнить. – mwilliams 2008-10-13 14:10:59

+1

Просто потому, что что-то возможно, это не значит, что это хорошая идея. ;) – epochwolf 2008-10-13 14:12:35

+0

Повышение исключения - это, безусловно, рубиновый способ сделать это. – rampion 2009-04-08 19:32:26

ответ

9

Я бы использовал set_var (var) вместо того, что вы пытаетесь сделать, считается, что автор сценария просто работает. То, что вы пытаетесь сделать, нестандартно и неочевидно для следующего бедного человека, чтобы использовать ваш код. (Это может быть только вы сами). Я бы выбрал исключение, если был отправлен плохой ввод или что-то довольно необычное.

Вы хотите, чтобы это поведение

Correct 
>>temp = object.var = 7 
=> 7 

Wrong 
>>temp = object.var = 7 
=> false 

Оператор = всегда должен возвращать значение, которое было передано ему. Ruby использует неявные возвращения, что редко встречается в языках программирования. Двойная проверка возвращается, когда вы используете method=().

+0

Я полностью согласен;) – 2008-10-13 14:44:14

2

Кроме того, в вашем примере, чтобы очистить вещи вы можете сделать следующее:

class MyClass 
    attr_accessor :var 
end 

m = MyClass.new 
m.var = "Test" 
puts m.var # => "Test" 

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

Update

Заканчивать этот проект: Validatable. Он добавляет ActiveRecord как проверки в атрибуты вашего класса.

Быстрый сценарий:

class Person 
    include Validatable 
    validates_presence_of :name 
    attr_accessor :name 
end 

class PersonPresenter 
    include Validatable 
    include_validations_for :person 
    attr_accessor :person 

    def initialize(person) 
    @person = person 
    end 
end 

presenter = PersonPresenter.new(Person.new) 
presenter.valid? #=> false 
presenter.errors.on(:name) #=> "can't be blank" 
4
class Test 
    def var=(var) 
    @var = var 
    return true 
    end 
end 

t1, t2 = Test.new, Test.new 

t1.var = 123 # evaluates to 123 

# Why is it impossible to return something else: 
t1.var = t2.var = 456 

Как указано в комментарии: Я считаю, что это невозможно изменить возвращаемое значение для того, чтобы позволить прикованных задания. Изменение значения возврата, вероятно, будет неожиданным для большинства программистов Ruby.

Отказ от ответственности: Я проверил код выше, но я не нашел явных ссылок для проверки моего заявления.

Update

class Test 
    def method_missing(method, *args) 
    if method == :var= 
     # check something 
     @var = args[0] 
     return true 
    else 
     super(method, *args) 
    end 
    end 

    def var 
    @var 
    end 
end 

t = Test.new 
t.var = 123 # evaluates to 123 
t.does_not_exists # NoMethodError 

Это действительно, кажется, невозможно! Вышеприведенный пример показывает, что возвращаемое значение не связано с методом var=. Вы не можете изменить это поведение - это основной способ работы Ruby.

Update 2: Решение найдено

Вы могли бы вызвать исключение!

class Test 
    def var=(var) 
    raise ArgumentError if var < 100 # or some other condition 
    @var = var 
    end 
    def var 
    @var 
    end 
end 

t = Test.new 
t.var = 123 # 123 
t.var = 1 # ArgumentError raised 
t.var # 123 
1

Я знаю, что это поздно ответ на вечеринку ...

Это трудно понять, что вы пытаетесь сделать с классом.Вы упомянули о необходимости проверить его перед сохранением ... в базе данных? файл?

Что бы вы хотели произойти в случае плохого значения атрибута?

С помощью логического возврата вы фактически «спрячете» ошибку (потому что вы будете забыть о странной вещи, связанной с проверкой возвращаемого значения сеттера).

В то время как вы можете делать то, что другие предложили

  • Использование средства проверки плагин
  • Raise ошибку

Вы можете также рассмотреть IsValid? метод, подобный многим классам, которые в конечном итоге сохраняются. Затем сохранение может проверить состояние объекта и выбросить ошибку.

Итог:

  • Не делать то, что вы вывесили
  • ли выдаст ошибку (любым из опубликованных решений)

Один из способов, чтобы помочь управлять решение (например, BDD). Затем проделайте свой путь дальше, чем должен заниматься класс TDD - используя RSpec, чтобы получить желаемый класс «контракт», который должен появиться для поддержки желаемого поведения.

 Смежные вопросы

  • Нет связанных вопросов^_^