混淆实例变量和局部变量

confused between instance variable and local variable

我最近开始学习ruby,我对实例变量和局部变量以及class变量感到困惑。所以,我最近编写的代码将在 1000 个素数中找到最大的回文。 代码是:

def prime_large(number)
  arr_prime = []
  Prime.each(number) do |x|
    new_arr_prime = arr_prime.push(x.to_s)
    updated = new_arr_prime.select { |y| y.reverse == y }
  end
  p updated.max 
end
p prime_large(1000)

我得到的错误是:

undefined local variable or method `updated' for main:Object (NameError)

我知道 updated 是 prime 的一个局部变量,所以我不能在它外面访问它,但我通过用 @updated 替换它来更改代码,如下所示:

def prime_large(number)
  arr_prime = []
  Prime.each(number) do |x|
    new_arr_prime = arr_prime.push(x.to_s)
    @updated = new_arr_prime.select { |y| y.reverse == y }
  end
  p @updated.max 
end
p prime_large(1000)

更改后,我得到了输出:

"929"
"929"

在我的代码中,没有创建 class 我的实例变量 (@updated) 是如何工作的。我对局部变量和实例变量感到困惑。任何人都可以向我解释差异及其工作原理吗?

在您的第一个示例中,您创建了一个 local 变量 updated,它只能在定义它的块的范围内访问。意思是,它是可用的仅在 Prime.each(number) do end 区块内。

在您的第二个示例中,您创建了 实例变量 @updated

without creating a class how my instance variable ( @updated) is working

这是因为在Ruby中一切都发生在某个对象的上下文中。即使您没有创建 class,您也处于顶级上下文中,在对象 main.

的上下文中

因此,在顶层中定义的任何实例变量都是该对象的实例变量main

所以回到你的问题,为了克服它,你只需要在 Prime.each(number) do end 块之外定义 updated 局部变量:

def prime_large(number)
  arr_prime = []
  updated   = nil # initialize local varialbe
  Prime.each(number) do |x|
    new_arr_prime = arr_prime.push(x.to_s)
    updated = new_arr_prime.select { |y| y.reverse == y } # assign new value
  end
  p updated.max 
end
p prime_large(1000)

要测试它你可以打开irb或者自己撬一下看看:

self               # the object in the context of which you are currently
#=> main
self.class         # main is an instance of class Object, any methods defined
                   # within main are added to Object class as instance methods
#=> Object
instance_variables # list of it's instance variables, none yet created
#=> []
@variable = 1      # create and instance variable
#=> 1
instance_variables # now created variable occurs in the list of current object's instance variables
#=> [:@variable]
def hello; :hello end # define method
#=> :hello
self.class.public_instance_methods(false) # list instance methods defined in Object
#=> [:hello]

您现在想要阅读的是 Ruby 中的词法作用域。