Ruby变量范围

Ruby变量范围,ruby,scope,Ruby,Scope,我一直在考虑学习一种新的用于web开发的动态脚本语言,在经历了Python和Ruby的痛苦之后,因为我真的很喜欢这两种语言,我决定选择Ruby(这几乎可以归结为掷硬币,事实上英国的RoR工作比Python/Django多)。我的问题是关于Ruby中的作用域。我必须在一个方法中声明一个class属性才能从其他方法访问它吗 例如,我做不到 class Notes @notes = ["Pick up some milk"] def print_notes puts @notes

我一直在考虑学习一种新的用于web开发的动态脚本语言,在经历了Python和Ruby的痛苦之后,因为我真的很喜欢这两种语言,我决定选择Ruby(这几乎可以归结为掷硬币,事实上英国的RoR工作比Python/Django多)。我的问题是关于Ruby中的作用域。我必须在一个方法中声明一个class属性才能从其他方法访问它吗

例如,我做不到

class Notes
  @notes = ["Pick up some milk"]

  def print_notes
    puts @notes
  end
end
似乎我必须声明我想在构造函数中使用的属性?此示例适用于:

class Notes
  def initialize
    @notes = ["Pick up some milk"]
  end

  def print_notes
    puts @notes
  end
end
是这样吗?我注意到示例一的前缀是@,而不是@works,但据我所知,如果该类有一个子类(例如,Memo),那么对Notes中前缀为@的属性的任何更改都会更改Memo中的值


很抱歉,如果这是一个重复的问题,只是一个丢失的noobie:)

当您在类中声明
@notes
,而不是在构造函数或任何实例方法中,那么您正在使
@notes
成为类本身实例的实例变量。每个类也作为
类的一个实例存在

class Notes
  @notes = ["Pick up some milk"]

      def print_notes
        puts @notes
      end
  end
# => nil
Notes.instance_variable_get(:"@notes")
# => ["Pick up some milk"]
所以答案是肯定的,您确实需要在构造函数或其他实例方法中声明实例变量。我认为您更愿意这样做:

class Notes
  def notes
    @notes ||= []
  end

  def print_notes
    puts @notes
  end
end

note = Notes.new
note.notes << "Pick up some milk"
note.notes
# => ["Pick up some milk"]
不是这个:

class Notes
  def notes
    @@notes ||= []
  end
end

当您需要一个类变量时。后者会给你带来麻烦。(但我认为这是一个不同的对话。)

这(您编写的最后一个代码片段)是否与使用
attr\u reader
attr\u writer
attr\u accessor
相同?如果是这样的话,这是做事情的首选方式吗?@Iain在附加信息之前的最后一个片段中?是和否。是的,这与
attr\u reader
相同。不,因为它定义了一个默认值而不是
nil
,我之所以这样做是因为它是一个数组,否则第一次设置它时,您必须使用
note.notes=[“whatever”]
。因为默认值是一个数组,所以实际上它的工作原理与
attr\u accessor
非常类似,因为您可以操作该值(数组)-虽然您不能使用
=
@Iain替换数组,因为您已经可以编程了,但我建议您阅读“Ruby中的元编程”关于范围及其如何影响事物的广泛讨论,但在互联网和其他书籍上有很多资源(也许其他人会建议一些)。
class Notes
  def notes
    @@notes ||= []
  end
end