Menu
CoddyTech

カスタムセッター

CoddyのRubyジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 8/57。

セッターは、名前が=で終わるメソッドです。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]

セッターは、エラーを発生させて値を拒否することもできます。値がチェックに合格した場合にのみインスタンス変数に代入されるため、オブジェクトは以前の状態を保ちます。

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

代入式は、セッターが返す値や保存する値ではなく、常に右辺の値を返します。保存された値を確認するには、属性をもう一度読み取ります。

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
challenge icon

チャレンジ

簡単

クラス Person を完成させてください。セッター name= は値の前後の空白を取り除き、各単語の先頭を大文字にします( ada lovelace は Ada Lovelace になります)。セッター age= は、年齢が 0 から 150 の範囲外の場合、メッセージ invalid age: 200 を伴う ArgumentError を発生させ、それ以外の場合は値を保存します。どちらの値も読み取ることができます。

新しい Person は、名前が Unknown、年齢が 0 の状態で始まります。提供されたコードは、name text または age n のコマンドを読み取り、セッターを通じて適用し、各コマンドの後に人物を Ada Lovelace (36) として出力します。セッターが値を受け付けない場合は、エラーメッセージを出力します。

コードは 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
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Rubyオンラインコンパイラ