自定义设置器
本课属于 Coddy Ruby 学习旅程的“面向对象编程”单元。第 8 课,共 57 课。
setter 是一种名称以 = 结尾的方法。自己编写 setter,而不是使用 attr_writer,可以在存储值之前先对其进行清理:
class Person
attr_reader :name
def name=(value)
@name = value.strip.capitalize
end
end
ada = Person.new
ada.name = " aDA "
puts "[#{ada.name}]"输出:
[Ada]setter 也可以通过引发错误来拒绝一个值。只有当值通过检查时,实例变量才会被赋值,因此对象会保留原来的状态:
class Product
attr_reader :price
def initialize(price)
@price = price
end
def price=(value)
raise ArgumentError, "price must be positive, got #{value}" if value <= 0
@price = value
end
end
item = Product.new(10)
begin
item.price = -5
rescue ArgumentError => e
puts e.message
end
puts item.price输出:
price must be positive, got -5
10赋值表达式总是返回其右侧的值,而不是 setter 返回或存储的值。再次读取属性,查看存储的值:
class Thermometer
attr_reader :celsius
def celsius=(value)
@celsius = value.round
end
end
t = Thermometer.new
result = (t.celsius = 21.7)
puts result
puts t.celsius输出:
21.7
22读取器和自定义设置器一起提供一个属性,外部代码可以读取和更改它,但只能设置为有效值。只在设置器中进行检查,这样每次更改都会遵循同一规则:
class Volume
attr_reader :level
def level=(value)
raise ArgumentError, "level must be 0-10" unless (0..10).cover?(value)
@level = value
end
end挑战
简单完成 Person 类。它的 setter name= 会去除值两端的空格,并将每个单词的首字母大写( ada lovelace 会变成 Ada Lovelace)。当年龄不在 0 到 150 之间时,它的 setter age= 会抛出 ArgumentError,并显示消息 invalid age: 200;否则会存储该值。两个值都可以读取。
新建的 Person 的名字为 Unknown,年龄为 0。提供的代码会读取 name text 或 age n 命令,通过 setter 应用这些命令,并在每条命令后将此人打印为 Ada Lovelace (36);如果 setter 拒绝该值,则打印错误消息。
你的代码写在 person.rb 中。main.rb 包含提供的输入/输出代码,不能编辑。
亲手试试
require_relative 'person'
# 提供的输入/输出代码:保持原样。
input = []
while (line = gets)
input << line.chomp
end
person = Person.new
input.each do |line|
command, value = line.split(" ", 2)
begin
command == "name" ? person.name = value : person.age = value.to_i
puts "#{person.name} (#{person.age})"
rescue ArgumentError => e
puts e.message
end
end
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Ruby 在线编译器