什么时候在Ruby中使用’self’

这个方法:

def format_stations_and_date from_station.titelize! if from_station.respond_to?(:titleize!) to_station.titleize! if to_station.respond_to?(:titleize!) if date.respond_to?(:to_date) date = date.to_date end end 

date为nil时失败并显示此错误:

 NoMethodError (You have a nil object when you didn't expect it! The error occurred while evaluating nil.to_date): app/models/schedule.rb:87:in `format_stations_and_date' app/controllers/schedules_controller.rb:15:in `show' 

但是,如果我将date = date.to_date更改为self.date = self.date.to_date ,则该方法可以正常工作。

这是怎么回事? 一般来说,我什么时候写self

编辑:这与问题无关,但请注意,没有“标题!” 方法。

每当你想在self上调用setter方法时,你必须编写self.foo = bar。 如果您只是编写foo = bar,那么ruby解析器会将其识别为变量赋值,并且从现在开始将foo视为局部变量。 为了让解析器实现,你要调用一个setter方法,而不是分配一个局部变量,你必须写obj.foo = bar,所以如果对象是self,self.foo = bar

您可以使用self消除实例方法名称和局部变量之间的歧义(允许在同一范围内具有相同的名称)。 换句话说,只有在范围内没有同名的本地或块变量时,才会有方法名称解析。 看吧:

 class Foo attr_accessor :boo def do_boo boo = 123 puts "Locvar: #{boo} Method: #{self.boo}" end end Foo.new.do_boo 

原因如下:假设您有一个实现方法的模块。 这个方法为它的内部局部变量“foo”赋予了一些东西,用于某些计算。 如果跳过“self”部分,该方法将对其类包含模块的对象进行“foo =”方法调用,这不是作者的意图,可能是彻头彻尾的灾难性的。

 class Foo def bar=(new_value_of_bar) set_off_nukes(new_value_of_bar / 3) end end module InnocentModule # written by a different author elsewhere def do_useful_stuff ... bar = Math.sin(something) # we're dead end end Foo.send(:include, InnocentModule) 

你必须使用self的另一个关键部分是在调用Object#类方法时,因为简单地说“class”意味着Ruby的类关键字。