在方法名称中放置方法名称后,等号('=')符号的作用是什么?

时间:2011-03-22 23:02:05

标签: ruby

我在截屏视频中看到了这一点,只是想知道在这种情况下'='符号是做什么的。

def express_token=(token)
...
end

我会理解是否是这样的 -

def express_token(token = nil) 

以上(第二个代码片段)表示将nil设置为tokens参数的默认值。但是,在第一个代码段中,“=”位于括号内。

提前致谢。

4 个答案:

答案 0 :(得分:79)

该片段定义了Virtual Attribute(或“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语句或最终值如何,此类setter方法总是返回其参数。

如果您正在定义顶级setter方法,例如,在“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="]

答案 1 :(得分:19)

这些方法允许您以更间接的方式设置实例变量:假设您有一个类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"

答案 2 :(得分:3)

它实际上是函数名称的一部分。所以它是一个setter,以防你需要不同于getter和setter的默认功能。

答案 3 :(得分:2)

让我们看看下面的例子:

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 =方法就像一个setter方法。同样如@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