体重計

体重計

学習演習

はじめに

ゲッターとセッターは、オブジェクトのプロパティの値を読み書きするためのメソッドです。 Crystalにはマクロがあるので、プロパティのゲッターとセッターを簡単に定義できます。 マクロはコンパイル時にコードを生成する仕組みで、これについては後のマクロの概念で扱います。

Rubyでは、これらのメソッドはattr_reader、attr_writer、attr_accessorというメソッドを使って定義され、表面的にはCrystalの実装とよく似ています。 Crystalでは、これらはgetter、setter、propertyというマクロとして定義しています。

ゲッター

ゲッターは、インスタンス変数の値を返すメソッドを定義するマクロです。 つまり、インスタンス変数にアクセスしたいときに(initializeを除くメソッド内で)その前に@を書く必要がなくなり、代わりにゲッターのマクロが定義したメソッドを呼び出せます。

ゲッターのマクロには、カンマで区切って複数のインスタンス変数を渡せます。

# This:
class Person
  @name : String
  @age : Int32

  def name
    @name
  end

  def age
    @age
  end
end

# Is the same as this:
class Person
  @name : String
  @age : Int32

  getter name, :age
end

見てのとおり、ゲッターを使うと書くコードの量が減り、読みやすくなります。 また、RubyとCrystalは、Crystalがゲッターのマクロの引数として変数名とシンボルの両方を受け付けるという点で異なります。 シンボルについては、後のシンボルの概念で扱います。

セッター

セッターは、インスタンス変数の値を設定するメソッドを定義するマクロです。 このマクロはあまり使われず、代わりにpropertyマクロがよく使われます。 作成されるメソッドはname_of_method=のようになります。この=があることで、プロパティを設定できるようになります。

このメソッド定義は少し特殊で、メソッドが受け取る引数が=記号の後に来ます。 Crystalの他のいくつかの特殊なメソッドも、+メソッドのようにこの構文を使います。

ゲッターのマクロと同様に、セッターを定義した後にインスタンス変数の値を更新したいときは、セッターのマクロが定義したメソッドを呼び出せます。

# This:
class Person
  @name : String
  @age : Int32

  def name=(name : String)
    @name = name
  end

  def age=(age : Int32)
    @age = age
  end
end

# Is the same as this:
class Person
  @name : String
  @age : Int32

  setter name, :age
end

プロパティ

プロパティは、インスタンス変数のゲッターとセッターの両方を定義するマクロです。

class Person
  @name : String
  @age : Int32

  property name, :age
end

説明

この演習では、はかりをモデル化します。

1. はかりの初期状態を作成する

初期化されるとき、はかりは工場出荷時の設定を参照する必要があります。この設定は、はかりが販売される地域によって異なります。 そのため、はかりは精度と、メートル法かヤード・ポンド法かの指定を付けて初期化できるようにします。

2つの引数を取るWeighingMachine#initializeメソッドを実装します。precisionはInt32、metricはBoolです。 metric引数がtrueのときはメートル法を、そうでなければヤード・ポンド法を使うことを意味します。 また、初期化メソッドでは、インスタンス変数@weightを0.0に設定します。

precision = 3
metric = true
vm = WeighingMachine.new(precision, metric)

2. はかりに精度を持たせる

さまざまな要求に応えるため、各はかりは精度(小数点以下の桁数)を指定してカスタマイズできるようにします。

WeighingMachine#precisionゲッターメソッドを実装し、はかりの精度を返すようにします。

precision = 3
metric = true
vm = WeighingMachine.new(precision, metric)
vm.precision
# => 3

3. はかりに重さを設定できるようにする

WeighingMachine#weightプロパティを実装し、重さの取得と設定の_両方_ができるようにします。

precision = 3
metric = true
wm = WeighingMachine.new(precision, metric)
wm.weight = 60.5
wm.weight
# => 60.5

wm.weigh
# => 60.5

4. メートル法とヤード・ポンド法を切り替えられるようにする

WeighingMachine#metric=プロパティを実装し、単位を設定できるようにします。 真偽値を受け取れるようにします。

precision = 3
metric = true
wm = WeighingMachine.new(precision, metric)
vm.weight = 60.5
wm.metric = false

vm.weigh
# => 133.377
GitHubで編集する リンクは新しいウィンドウまたはタブで開きます
Crystal Exercism

体重計を始める準備はできましたか?

Exercismに登録すれば、26個のコンセプト142個の演習、そして本物の人間によるメンタリングとともに、Crystalを学んでマスターできます。すべて無料です。