不使用self而从模型设置属性不起作用

Ant*_*nAL 4 ruby ruby-on-rails naming-conventions self

设备模型具有以下属性:name,version和full_name

全名是name + version:

class Device < ActiveRecord::Base
  def prepare
    full_name = (!show_version || version.nil?)? name : name + " " + version.to_s
  end
end
Run Code Online (Sandbox Code Playgroud)

当我做以下时:

d = Device.new :name => "iPhone", :version => "4"
d.prepare
d.full_name # get nil
Run Code Online (Sandbox Code Playgroud)

我的"full_name"属性为nil

当我使用"自我"时,它有效:

class Device < ActiveRecord::Base
  def prepare
    self.full_name = (!show_version || version.nil?)? name : name + " " + version.to_s
  end
end
Run Code Online (Sandbox Code Playgroud)

做"准备"我得到"iPhone 4"的"full_name"属性.

这里的一些人告诉我,避免在类方法中使用"自我"是一种好方法.但这带来了麻烦.

问题是 - 为什么不使用"自我"就行不通?

dom*_*esz 13

在这些情况下你必须使用自我,我不认为这是一个麻烦.如果您正在使用,self则解释器将知道您引用对象的属性.如果你不使用self它意味着它只是一个局部变量,在方法完成后没有存储在任何地方.这是正常的行为.您也可以使用self[:full_name]= ...setter方法,但在这种情况下并不重要.

更新

@AntonAL

因为没有使用getter方法self..

当您尝试使用该name属性时,解释器将在当前方法中查找局部变量.如果未找到,则查找实例属性.例:

def your_method
  self.name = 'iPhone'
  puts name
  #iPhone
  name = 'iPod'
  puts name
  #iPod
  puts self.name
  #iPhone
end
Run Code Online (Sandbox Code Playgroud)

并且iPhone将存储在你的对象实例的name属性.并且iPod在方法完成后将丢失.


rub*_*nce 13

当您使用setter时,您需要使用self,否则Ruby会将其解释为full_name正在定义的新局部变量.

对于getter,我们不需要调用self因为Ruby首先搜索局部变量full_name,当它没有局部变量时full_name,它将搜索一个方法full_name并获得getter.如果定义了局部变量full_name,它将返回局部变量的值.

在前一个问题中得到了更好的解释

  • @PeterLee ..最好对getter和setter都明确使用`self`,以使其更统一。 (2认同)
  • @gwho.现在我不使用`self`作为getter,但仅限于setter,因为我现在遵循这个[styleguide](https://github.com/bbatsov/ruby-style-guide)(部分原因在于代码审查工具)例如[rubocop](https://github.com/bbatsov/rubocop)坚持不使用`self`,除非有必要.我们现在作为一个团队遵循这个样式指南).但是,当我使用`self`作为吸气剂时,我实际上使用`self`作为关联也使它在整个过程中均匀. (2认同)