8

可能重复:
为什么 Ruby setter 需要“self”。班级内的资格?

有人可以解释以下之间的区别,以及为什么它不像人们所期望的那样:

# version #1
class User
  def initialize(name, age)
    @name = name
    @age = age
  end
end

#version #2
class User
  attr_accessor :name, :age
  def initialize(name, age)
    @name = name
    @age = age
  end
end

#version #3
class User
  attr_accessor :name, :age
  def initialize(name, age)
    self.name = name
    self.age = age
  end
end

据我了解,在方法中,分配时必须使用self关键字。为什么不能在initialize方法中使用它?或者你可以吗?我尝试使用它,但它似乎没有按预期工作,我只是对使用哪种技术以及何时使用以及更重要的是为什么感到困惑。

我真的希望有人可以一劳永逸地为我解决这个问题:)

4

2 回答 2

16

Version 1: The constructor creates two instance variables, @name and @age. These two variables are private (as are all Ruby instance variables), so you can't access them outside of the class.

Version 2: Exact same thing as #1 except that you're also defining a getter and setter method for the two variables. What attr_accessor does is create two methods for each parameter that allow you to get/set the value of the instance variable with the same name.

Version 3: Exact same as #2 except that in your constructor you're not setting the instance variables directly, instead you're calling the User#name= and User#age= methods to set the value of your instance variables instead of setting them directly.

To clarify the difference between setting the instance variable directly and calling a setter method, consider this example:

user = User.new "Rob", 26
user.name = "Joe"

Here you are not actually setting the @name variable of user directly, instead you are calling a method called name= on user which sets the value of @name for you. When you did the call to attr_accessor in versions #2 and #3, it defined that method for you. However in version #1 you did not call attr_accessor, so the example above would be invalid since there is no name= method.

于 2012-09-02T23:47:15.123 回答
0

您不需要在方法中使用 self ;对于实例变量,您应该直接使用@ 进行赋值,就像在版本 1 或 2 中一样。self 不像在 Python 中那样;例如,它用于声明类方法(如 C++ 中的静态函数)。

于 2012-09-02T23:39:02.100 回答