无法理解Ruby中实例变量的范围

问题描述

我有两组代码

@movies = ["Zoolander","Sandlot"]

def good_movies
    @movies.each do |movie|
    puts "I love #{movie}!"
    end
end

good_movies
#I love Zoolander!
#I love Sandlot!

我了解局部变量的范围,因此必须有实例变量才能使代码运行,否则我将收到NameError

但是涉及到这一点

class Example
  
   @scope = "This is the scope of the class itself"

   def hello
       p @scope 
   end

 end

ex = Example.new
ex.hello 
# nil

看起来无法访问预定义的实例变量,但没有收到错误。它应该与实例化有关,但我不知道具体的原因。 谁能给我一些指导吗?

解决方法

看起来无法访问预定义的实例变量,但我没有收到错误。

访问未定义的instance variable不会引发异常,它只会返回nil

由于您是在类对象本身上定义了实例变量,因此需要在同一scope中使用一个方法来访问它,即 class方法

class Example
  @scope = "This is the scope of the class itself"

  def self.hello
    p @scope
  end
end

Example.hello
#=> "This is the scope of the class itself"

要为您的实例定义变量,请使用initialize :(因此每个实例都有自己的@scope

class Example
  def initialize
    @scope = "This is the scope of an instance"
  end

  def hello
    p @scope
  end
end

ex = Example.new
ex.hello
#=> "This is the scope of an instance"

您还可以通过Object#class访问实例的类,并通过instance_variable_get访问实例的变量:

class Example
  @scope = "This is the scope of the class itself"

  def hello
    p self.class.instance_variable_get(:@scope)
  end
end

ex = Example.new
ex.hello
#=> "This is the scope of the class itself"

显然,这违反了任何封装工作。如果您确实想这样做,则应定义一个吸气剂:

class Example
  @scope = "This is the scope of the class itself"
  class << self
    attr_reader(:scope)
  end

  def hello
    p self.class.scope
  end
end

ex = Example.new
ex.hello
#=> "This is the scope of the class itself"

Example.scope
#=> "This is the scope of the class itself"