2012-02-08 3 views
3
class Person < ActiveRecord::Base 
    validates :terms_of_service, :acceptance => true 
end 

В приведенном выше, что такое validates с точки зрения Ruby? Его не метод определение, его не определение данных или декларация, поэтому, очевидно, его метод invocation, прямо там, в теле класса. Я никогда не видел метод, вызываемый таким же образом непосредственно в классе (т. Е. Вне определения метода), даже в учебнике по программированию Ruby, который я сейчас просматриваю: http://ruby-doc.org/docs/ProgrammingRuby/.вызов метода в определении класса?

Итак, если это вызов метода, в какой момент он вызывается. Я попробовал следующее как тест:

class Person 

    print "cat" 

end 

#p = Person.new 
#q = Person.new 

print "cat" в настоящее время выполняется только один раз, независимо от того, какие реальные объекты Person объявляются или нет, так что, очевидно, только при анализе определения класса, Ruby видит метод печати и говорит , «ОК, я просто продолжу и выполняю это сейчас», но никогда не делает этого снова.

SO где документация рубин, которая поможет мне понять, что происходит с validates выше

Спасибо.

+0

Это было долгое время, так как я я прочитал «Программирование Ruby», но я * довольно * уверен, что сообщения, отправленные в классах, рассматриваются очень рано, особенно 'attr_reader',' attr_writer' и 'attr_accessor'. –

ответ

8

В Ruby объявления классов - это просто фрагменты кода, выполненные по порядку.

Важно помнить, что внутри определения класса self указывает на сам класс. validates - метод класса ActiveRecord. Когда класс определяется, выполняется код в определении. Метод validates разрешает метод класса ActiveRecord, поэтому он называется при определении класса.

В примере вашего Person он будет печататься только один раз, потому что вы определяете только один класс.

Рассмотрим следующий пример:

class Foo 
    def self.validates_nothing(sym) 
    (@@syms ||= []) << sym 
    puts "!!! Here there be logic" 
    end 

    def validate 
    @@syms.each { |s| puts s } 
    end 
end 

Это определяет класс с методом класса validates_nothing, и метод экземпляра, validate. validates_nothing просто собирает все аргументы, validate просто сбрасывает их.

class Bar < Foo 
    validates_nothing :anything 
    validates_nothing :at_all 
end 

Это определяет подкласс. Обратите внимание, что, когда метод класса validates_nothing называется, она печатает:

Here there be logic 
Here there be logic 

Если мы создаем новую строку и вызвать Validate, мы получим ожидаемый результат:

> Bar.new.validate 
!!!anything 
!!!at_all 
+0

ТАК, как «проверяется» выполнение в Rails. «print cat» не вызывается на новый (где я бы предположил, что он будет вызываться). Его просто называют один раз, когда интерпретатор Ruby впервые встречает «печатный кот» в тексте, а затем больше никогда не появляется. – Mark

+0

@Mark Как? Поскольку определение класса состоит из кода Ruby, который выполняется * при определении класса *. Вызов 'new' не определяет класс, он создает новый экземпляр.'validates' вызывается * во время самого процесса определения класса *. Вы считаете, что тело определения класса выполняется во время «нового», но это неверно и не имеет смысла - это подразумевает, что определения методов, например, будут повторно выполняться (или определяться или что-то еще). –

+0

Итак, медведь со мной здесь, в приведенном выше примере проверки, проверка правильности называется ровно один раз, независимо от того, сколько объявленных объектов Person объявлено? – Mark

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