Menu
Coddy logo textTech

カスタムセッター

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オンラインコンパイラ