在调用实例变量

时间:2017-01-15 02:01:09

标签: ruby variables

当你有一个带有attr_accessor的课程时,在调用你的实例变量时你是否可以省略@符号,因为如果你不使用@符号,那么会隐含self.instance_variable?

4 个答案:

答案 0 :(得分:0)

如果您有attr_accessor且想要读取该值,则会得到相同的值。你不是在省略@,而是在调用一个返回实例变量的同名方法。

尝试设置值时省略@将不会以相同的方式工作;它只会设置一个具有相同名称的局部变量。在对象中使用对象的setter需要在其前面加self.

class Foo
  attr_accessor :bar

  def getter_equivalent?
    bar.equal?(@bar) # Returns true. They are the same object.
  end

  def set_with_at(value)
    @bar = value  # Will set the instance variable
  end

  def set_without_at(value)
    bar = value  # Will not set the instance variable
  end

  def set_with_self(value)
    self.bar = value  # Will set the instance variable
  end

end

答案 1 :(得分:0)

为了清晰起见,展开了attr_accessor的类示例。通常的initialize方法已被忽略,专注于手头的任务:

class Foo

  def bar
    @bar
  end

  def bar=(bar)
    @bar = bar
  end    

  #the above two methods represent attr_accessor :bar      

  def call_method
    bar
    #same as self.bar
    #self refers to the current object i.e. the current instance of Foo
    #bar refers to the method bar defined above
  end

  def call_instance_var
    @bar
    #refers directly to the the instance variable
  end
end

你可以使用其中任何一个,我个人更喜欢调用方法而不是实例变量。

实施例

foo = Foo.new
foo.bar = "bar"
foo.call_method       #=> "bar"
foo.call_instance_var #=> "bar"

答案 2 :(得分:0)

attr_accessor :foo基本上只是一种为您生成两种方法(getter和setter)的方法:

def foo
  @foo
end

def foo=(foo)
  @foo = foo
end

那么,在调用实例变量时可以省略@吗? - 调用不带@的实例变量名称意味着您正在调用由attr_accesor生成的实例方法,而不是调用实例变量。只要不覆盖或扩展getter方法,这就可以工作。

但是当你试图设置一个没有@的实例变量时,它就不会那样工作。因为Ruby会设置一个具有该名称的局部变量。要通过attr_accessor生成的实例方法设置实例变量,您需要编写self.(或其他接收者)而不是@

@foo = 'bar'      # assigns `'bar'` to the instance variable `@foo`
foo = 'bar'       # assigns `'bar'` to a local variable `@foo`

但要使用attr_accessor生成的setter方法:

self.foo = 'bar'  # passes `'bar'` to `self` instance method `foo=`

答案 3 :(得分:0)

尽管可以在类中使用访问器方法,但最好使用@符号来引用实例变量。

以下是在类中使用reader方法会产生意外结果的示例:

class A

  def var
    @var
  end

  def defined_using_method?
    defined?(var)
  end

  def defined_using_at?
    defined?(@var)
  end

end

A.new.defined_using_method? # => "method"
A.new.defined_using_at? # => nil