Что делает символ equal ( ' = ' ), когда он помещается после имени метода в определении метода?


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

def express_token=(token)
...
end

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

def express_token(token = nil) 

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

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

4 54

4 ответа:

этот фрагмент определяет Виртуальный Атрибут (или метод "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", то поведение может быть немного запутанным из-за неявного добавления методов к классу объектов. Например:

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="]

эти методы позволяют установить экземпляр vars более косвенным образом: представьте, что у вас есть класс 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"

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

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

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  

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

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