как использовать ключевое слово self в рельсах - PullRequest
4 голосов
/ 13 января 2012

относительно ключевого слова "self" в рельсах, давайте возьмем фрагмент кода ниже, например.Я знаю, что ключевое слово относится к экземпляру самого класса, например, для выражения «self.encrypted_password».во всяком случае, я получил гораздо меньше представления о том, почему атрибут «пароль», передаваемый в качестве параметра с правой стороны, также не имеет префикса с ключевым словом «self»?Ключевое слово self, следуя моему примеру, дает?

 class User < ActiveRecord::Base

      attr_accessor :password
      attr_accessible  :name, :email, :password, :password_confirmation

      validates :password, :presence     => true,
                           :confirmation => true,
                           :length       => { :within => 6..40 }

      before_save :encrypt_password

      private

        def encrypt_password
          self.encrypted_password = encrypt(password)
        end

        def encrypt(string)
          string # Only a temporary implementation!
        end
    end

Ответы [ 3 ]

8 голосов
/ 13 января 2012

Ответ

Ответ прост: видимость области действия.

def encrypt_password
  self.encrypted_password = encrypt(password)
end

Существует (или, скорее, должно быть во время выполнения) что-то , называемое password. В вашем случае это атрибут из базы данных. Но это также может быть локальной переменной. Если такое имя не найдено, появится ошибка.

Но у вас есть для префикса encrypted_password с self, чтобы явно указать, что вы собираетесь обновить атрибут экземпляра. В противном случае будет создана новая локальная переменная encrypted_password. Очевидно, не тот эффект, который вы хотели.

Больше объяснений

Вот небольшой фрагмент кода

class Foo
  attr_accessor :var

  def bar1
    var = 4
    puts var
    puts self.var
  end
end

f = Foo.new
f.var = 3
f.bar1

выход

4
3

Итак, как мы видим, var назначается без ключевого слова self, и поэтому теперь в области видимости есть два имени var: локальная переменная и атрибут экземпляра. Атрибут экземпляра скрыт локальной переменной, поэтому, если вы действительно хотите получить к нему доступ, используйте self.

2 голосов
/ 13 января 2012

Вопрос не имеет ничего общего с Rails, но с Ruby.Когда вы посмотрите на свой код:

def encrypt_password
  self.encrypted_password = encrypt(password)
end

, он будет переведен Ruby на:

  • self.encrypted_password = - это вызов метода encrypted_password= метода.
  • Этот метод генерируется Rails на лету, поскольку существует столбец базы данных с тем же именем.
  • encrypt(password) содержит 2 вызова методов.

    1. password вызывает метод password, который является реальным атрибутом модели по объявлению attr_accessor :password.Это объявление создает два метода:
      • password: получатель атрибута
      • password=: установщик атрибута

    См.объяснение @Sergio_Tulentsev, как геттер может быть скрыт локальной переменной (что не так в вашей реализации, нет локальной переменной).

    1. Вызывает метод encrypt с возвратомзначение вызова метода password.

Таким образом, использование self. делает очевидным, что у вас (все время) есть вызов метода, к которому вы не обращаетесьатрибут напрямую.Если вы хотите сделать это, вы должны использовать @password = <some value> внутри метода экземпляра, но мне нравится стиль с self.password = <some value> гораздо больше.

Надеюсь, теперь понятно, как интерпретируется ваш код.

0 голосов
/ 13 января 2012

метод установки => использовать себя

Используйте self, когда вам нужно написать что-то.Другими словами, когда вам нужно присвоить значение.

getter method => не используйте self

И without self, когда вам нужно прочитайте что-то.Когда вам нужно прочитать значение.

, например:

def write_name(name)
  self.name = name
end

def read_name
  name
end

В вашем случае виртуальный атрибут password не имеет префикса с ключевым словом self, потому что это *Только 1024 * read (getter).

encrypted_password - это то, что будет храниться в базе данных, записано в db (setter).Таким образом, использование self.

Edit :

Michael HARTL имеет то же самое объяснение относительно того же самого случая:

(Конечно, как мы уже отмечали, self не является обязательным при назначении атрибута, поэтому в этом случае мы должны написать self.encrypted_password.)

http://ruby.railstutorial.org/chapters/modeling-and-viewing-users-two#sec:an_active_record_callback

(последние строки 7.1.3)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...