关于ruby:将等号(‘=’)放在方法定义中的方法名称后会有什么作用?

What does the equal ('=') symbol do when put after the method name in a method definition?

我在截屏中看到了这一点,只是想知道在这种情况下'='符号的作用。

1
2
3
def express_token=(token)
...
end

我会明白是否是这样的-

1
def express_token(token = nil)

上面的代码(第二段代码)意味着将nil设置为tokens参数的默认值。 但是,在第一个代码段中," ="在方括号之外。


该代码段定义了虚拟属性(或" setter"方法),以使" express_token"看起来像属性,即使它只是方法的名称。例如:

1
2
3
4
5
6
7
8
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方法始终返回其参数。

如果要在" irb"中定义顶级设置方法,则由于隐式向Object类添加了方法,因此该行为可能会有些混乱。例如:

1
2
3
4
5
6
7
8
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="]


这些方法使您可以以更间接的方式设置实例变量:假设您有一个类Person

1
2
3
4
5
6
7
8
9
10
11
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

然后,您可以执行以下操作:

1
2
3
4
5
p = Person.new
p.full_name ="John Doe"
p.first_name # =>"John"
p.last_name # =>"Doe"
p.full_name # =>"John Doe"

让我们看下面的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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方法重构为:

1
2
3
def name=(nm)  
  @name = nm  
end

其他程序员知道name =方法充当setter方法。也如@maerics所示,它的行为类似于虚拟属性。

结果看起来像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

它实际上是函数名称的一部分。因此,这是一个设置器,以防万一需要getter和setter的功能而不是默认功能。