Ruby:从内部方法访问attr_accessor的方法

Kur*_*aga 2 ruby attr-accessor

我有一个代码:

class A
  attr_accessor :somevar

  def a
    somevar = 'something'
    puts @somevar
  end

  def b
    send :somevar=, 'something'
    puts @somevar
  end

end

A.new.a #=> nil
A.new.b #=> 'something'
Run Code Online (Sandbox Code Playgroud)

为什么会有区别?为什么我不能通过编写器分配实例变量?但是为什么已经调用了局部变量而不是方法(setter)呢?

quu*_*x00 7

attr_accessor :somevar引用实例变量@somevar.实例变量必须以@符号开头.所有其他变量,如'somevar',@在方法中没有符号,只是该方法或范围的局部变量,而不是对象的实例变量.

因此,将方法"a"中的第一行更改为

@somevar = 'something'
Run Code Online (Sandbox Code Playgroud)

将产生您期望的答案.

相关说明:您不必在Ruby中声明实例变量,只需使用@somevar类型表示法创建它们.该attr_accessor方法为该实例变量创建setter和getter.

Ruby中的方法附加到对象,因此为了让A类调用自己的somevar setter方法,您需要编写self.somevar = 'something',否则Ruby解析器会认为您只是创建了一个局部变量.

这可能是令人困惑,因为你可以调用方法ab通过只是在做:

def b
  send :somevar=,'something'
  puts @somevar
  a  # would invoke its own method 'a'
end
Run Code Online (Sandbox Code Playgroud)

但是setter方法somevar=与使用相同的表示法创建局部变量是不明确的:

somevar='something'  # Ruby assumes you want to create a local variable
Run Code Online (Sandbox Code Playgroud)

所以要调用somevar setter方法,你需要明确地说你在自己上调用方法:

self.somevar = 'something'
Run Code Online (Sandbox Code Playgroud)

当你调用时,send :somevar=,'something'你也调用了somevar实例方法.