在方法定义的方法名称后面加上等于(’=’)符号有什么作用?

我在一个视频中看到了这个,我只是想知道’=’符号在这个示例中有什么作用。

def express_token=(token)
...
end

如果是这样,我会理解的

def express_token(token = nil)

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

26482 次浏览

Its actually part of the name of the function. So it's a setter, in case you need separate functionality than default for getters and setters.

Those methods let you set instance vars in a more indirect way: imagine you have a class 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

Then you can do something like this:

p = Person.new
p.full_name = "John Doe"
p.first_name # => "John"
p.last_name # => "Doe"
p.full_name # => "John Doe"

That snippet defines a Virtual Attribute (or a "setter" method) so that "express_token" looks like an attribute, even though it's just the name of the method. For example:

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

Note that the object "f" has no attribute or instance variable named "foo" (nor does it need one), so the "foo=" method is just syntactic sugar for allowing a method call that looks like an assignment. Note also that such setter methods always return their argument, regardless of any return statement or final value.

If you're defining a top-level setter method, for example, in "irb", then the behavior may be a little confusing because of the implicit addition of methods to the Object class. For example:

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

Let's take a look at the following example:

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

If you refactor the setter method to this:

def name=(nm)
@name = nm
end

other programmers know that the name= method behaves as a setter method. Also as show by @maerics it behaves like a virtual attribute.

The result looks like this:

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