Ruby 中的属性访问器
attr_accessor
是 Ruby OOP 设计中 attr_reader
和 attr_writer
的快捷方式。
因此,要了解 attr_accessor
,你必须首先了解 attr_reader
和 attr_writer
是如何工作的。为了说明这些是如何工作的,我们将创建一个简单的类。
在 Ruby 中使用简单类创建实例变量 full_name
class Employee
def initialize(last_name, first_name)
@full_name = "#{last_name} #{first_name}"
end
end
employee1 = Employee.new("John", "Doe")
puts employee1.full_name
输出:
undefined method 'full_name' for #<Employee:0x0000558c7cbc9400 @full_name="John Doe"> (NoMethodError)
上面的简单 Employee
类有一个构造函数,它接受员工的姓氏和名字,并使用它来创建实例变量 full_name
。
如果我们创建这个类的一个实例并读取 full_name
,我们会收到 NoMethodError
错误,如上面的输出所示。我们将需要创建另一个返回实例变量的方法。
class Employee
def initialize(last_name, first_name)
@full_name = "#{last_name} #{first_name}"
end
def full_name
@full_name
end
end
employee1 = Employee.new("John", "Doe")
puts employee1.full_name
输出:
John Doe
在 Ruby 中使用 attr_reader
来读取多个实例变量
这是否意味着如果我们有多个需要读取的实例变量,我们将不得不为每个变量创建一个方法?
那会使我们的课不必要地长。因此,Ruby 为我们提供了 attr_reader
来实现这一点。
class Employee
attr_reader :full_name
def initialize(last_name, first_name)
@full_name = "#{last_name} #{first_name}"
end
end
employee1 = Employee.new("John", "Doe")
puts employee1.full_name
输出:
John Doe
正如你在上面的代码中看到的,我们的输出与前面的代码相同。attr_reader :full_name
的添加在底层添加了 full_name
方法,允许我们编写一个简洁的类。
假设我们还需要重置实例变量。我们可能会尝试这样的事情:
class Employee
attr_reader :full_name
def initialize(last_name, first_name)
@full_name = "#{last_name} #{first_name}"
end
end
employee1 = Employee.new("John", "Doe")
# After doing some operation on employee1 and we need
# to rename the full name
employee1.full_name = "Nicolas Daniel"
输出:
undefined method 'full_name=' for #<Employee:0x000055bc12240940 @full_name="John Doe"> (NoMethodError)
一种方法是定义一个重置实例变量的 full_name=
setter 方法。
class Employee
attr_reader :full_name
def initialize(last_name, first_name)
@full_name = "#{last_name} #{first_name}"
end
def full_name=(name)
@full_name = name
end
end
employee1 = Employee.new("John", "Doe")
# After doing some operation on employee1 and we need
# to rename the full name
employee1.full_name = "Nicolas Daniel"
puts employee1.full_name
输出:
Nicolas Daniel
在 Ruby 中使用 attr_writer
编写多个实例变量
Ruby 并没有像我们在这里所做的那样定义一个单独的 setter 方法,而是为我们提供了可以帮助我们的 attr_writer
。
class Employee
attr_reader :full_name
attr_writer :full_name
def initialize(last_name, first_name)
@full_name = "#{last_name} #{first_name}"
end
end
employee1 = Employee.new("John", "Doe")
# After doing some operation on employee1 and we need
# to rename the full name
employee1.full_name = "Nicolas Daniel"
puts employee1.full_name
输出:
Nicolas Daniel
正如我们在上面的输出中所看到的,即使我们删除了之前定义的 setter
方法,添加 attr_writer
也得到了相同的结果。
在 Ruby 中将 attr_reader
和 attr_writer
组合成 attr_accessor
我们的最终代码比为每个实例变量定义 getter 和 setter 方法要好得多,但是 Ruby 仍然允许我们通过将 attr_reader
和 attr_writer
组合到 attr_accessor
中更进一步。
class Employee
attr_accessor :full_name
def initialize(last_name, first_name)
@full_name = "#{last_name} #{first_name}"
end
end
employee1 = Employee.new("John", "Doe")
# After doing some operation on employee1 and we need
# to rename the full name
employee1.full_name = "Nicolas Daniel"
puts employee1.full_name
输出:
Nicolas Daniel
正如我们在上面看到的,使用 attr_accessor
,我们会自动为实例变量创建一个 getter 和一个 setter。