Подтвердить что ты не робот

Когда использовать `self.foo` вместо` foo` в Ruby-методах

Это не относится к Rails - я просто использую Rails в качестве примера.

У меня есть модель в Rails:

class Item < ActiveRecord::Base

  def hello
    puts "Hello, #{self.name}"
  end
end

(Скажем, что модель (класс) Item имеет метод, называемый name). Когда мне нужно использовать self.name и когда я могу просто использовать name? (Например, #{name})

4b9b3361

Ответ 1

  • Идиоматично предпочитать опускать self. при вызове методов; это обычно никогда не требуется.

  • <self.foo = xxx при вызове метода setter вместо foo = xxx, так что Ruby понимает, что вы не пытаетесь создать новую локальную переменную.
  • Аналогично, в маловероятном случае, если у вас есть существующая локальная переменная do_something с тем же именем, что и метод, вы должны использовать self.do_something для вызова метода, так как только do_something закончит чтение переменной.

Вы не можете использовать self.foo(...) для вызова частного метода; вы должны вместо этого называть только foo(...).

Ответ 2

Если вы опустите self, Ruby сначала ищет локальные переменные с этим именем, а затем для метода экземпляра. Это не идиоматично писать self.. В любом случае вам нужно написать self.something = value при назначении.

Обратите внимание, что вы не можете использовать self при вызове частных методов (без проблем с защищенными методами):

class A
  def foo; self.bar; end

private

  def bar; "bar"; end
end

A.new.foo  
# private method `bar' called for #<A:0x7f49193584f0> (NoMethodError)

Ответ 3

Следуя этому руководству, вам не нужно использовать self-указатель. Но я думаю, что это (или я в нашем случае) указатели используются для разрешения конфликтов имен. На самом деле, @name и self.name - это те же самые утверждения (если для вашего класса нет метода name). Например:.

class Moo
  attr_accessor :name

  def moo(name)
    name = name # O_o which *name* should i use?
  end

  def foo(name)
    @name = name # the same as *self.name = name*
  end

  def hello
    puts self.name # the same as *puts @name*
  end
end

a = Moo.new
a.hello() # should give no output

a.moo('zaooza')
a.hello() # Hey! Why does it prints nothing?

a.foo('zaooza')
a.hello() # whoa! This one shows 'zaooza'!

Попробуйте запустить этот код, и вы увидите =)