Что символ равенства ('=') делает, когда ставится после имени метода в определении метода? - PullRequest
60 голосов
/ 23 марта 2011

Я видел это в скринкасте, и мне было просто интересно, что символ '=' делает в этом случае.

def express_token=(token)
...
end

Я бы понял, если бы это было что-то вроде этого -

def express_token(token = nil) 

Выше (второй фрагмент кода) означает установку nil в качестве значения по умолчанию для параметра токенов. Однако в первом фрагменте кода «=» находится за скобками.

Заранее спасибо.

Ответы [ 4 ]

79 голосов
/ 23 марта 2011

Этот фрагмент определяет Виртуальный атрибут (или метод "setter"), так что "express_token" выглядит как атрибут, даже если это просто имя метода.Например:

class Foo
  def foo=(x)
    puts "OK: x=#{x}"
  end
end
f = Foo.new
f.foo = 123 # => 123
# OK: x=123

Обратите внимание, что у объекта "f" нет атрибута или переменной экземпляра с именем "foo" (и при этом он не нужен), поэтому метод "foo =" является просто синтаксическим сахаром для разрешениявызов метода, который выглядит как присваивание.Также обратите внимание, что такие методы установки всегда возвращают свой аргумент независимо от оператора return или конечного значения.

Если вы определяете метод установки верхнего уровня, например, в«irb», то поведение может быть немного запутанным из-за неявного добавления методов к классу Object.Например:

def bar=(y)
  puts "OK: y=#{y}"
end
bar = 123 # => 123, sets the variable "bar".
bar # => 123
Object.new.bar = 123 # => 123, calls our method
# OK: y=123
Object.public_methods.grep /bar/ # => ["bar="]
19 голосов
/ 23 марта 2011

Эти методы позволяют устанавливать переменные экземпляра более косвенным образом: представьте, что у вас есть класс Person

class Person < ActiveRecord::Base
  attr_accessible :first_name, :last_name

  def full_name
    [@first_name, @last_name].join
  end

  def full_name=(name)
    @first_name, @last_name = name.split(" ")
  end
end

Тогда вы можете сделать что-то вроде этого:

p = Person.new
p.full_name = "John Doe"
p.first_name # => "John"
p.last_name # => "Doe"
p.full_name # => "John Doe"
3 голосов
/ 23 марта 2011

На самом деле это часть имени функции.Так что это сеттер, если вам нужна отдельная функциональность, отличная от стандартной для геттеров и сеттеров.

2 голосов
/ 22 ноября 2016

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

class NewDog  
  def initialize(breed)  
    @breed = breed  
  end

  # create reader only
  attr_reader :breed, :name 

  # setter method  
  def set_name(nm)  
    @name = nm  
  end  
end  

nd = NewDog.new('Doberman')  
nd.set_name('Benzy')  
puts nd.name  

Если вы измените метод установки следующим образом:

def name=(nm)  
  @name = nm  
end 

другие программисты знают, что метод name = ведет себя какметод установки.Также, как показывает @maerics, он ведет себя как виртуальный атрибут.

Результат выглядит следующим образом:

class NewDog  
  def initialize(breed)  
    @breed = breed  
  end  

  # create reader only  
  attr_reader :breed, :name 

  # setter method  
  def name=(nm)  
    @name = nm  
  end  
end  

nd = NewDog.new('Doberman')  
nd.name = 'Benzy'  
puts nd.name 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...