آلة الوزن

آلة الوزن

تمرين تعلّمي

مقدمة

الـgetter والـsetter طريقتان تتيحان لك قراءة قيمة خاصية كائن وكتابتها. تمتلك Crystal ماكروات، وهذا يسهّل تعريف getter وsetter لخاصية ما. الماكروات وسيلة لتوليد الكود في وقت الترجمة، وسنغطيها لاحقًا في مفهوم الماكرو.

في Ruby تُعرَّف هذه الطرق باستخدام الطرق attr_reader وattr_writer وattr_accessor، وهي تشبه من حيث المظهر تطبيق Crystal لها إلى حد كبير. وقد عرّفت Crystal هذه في صورة ماكروات getter وsetter وproperty.

الـgetter

getter ماكرو يعرّف طريقة تُرجع قيمة متغير نسخة. وهذا يعني أنك لم تعد مضطرًا لكتابة @ أمام متغير النسخة عندما تريد الوصول إليه (داخل الطرق، باستثناء initialize)؛ وبدلًا من ذلك يمكنك استدعاء الطريقة التي عرّفها ماكرو getter.

يمكن لماكرو getter أن يقبل عدة متغيرات نسخة تفصل بينها فواصل.

# 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

كما ترى، يقلّل استخدام getter من كمية الكود الذي تكتبه، ويجعل قراءته أسهل. وتختلف Crystal عن Ruby أيضًا في أنها تقبل اسم المتغير والرمز معًا كوسائط لماكرو getter. وسنغطي الرموز لاحقًا في مفهوم الرموز.

الـsetter

setter ماكرو يعرّف طريقة تضبط قيمة متغير نسخة. لا يُصادف هذا الماكرو كثيرًا، وعادةً يُستخدم ماكرو property بدلًا منه. ستبدو الطرق التي ستُنشَأ على هيئة name_of_method=؛ فعلامة = هي ما يتيح ضبط الخاصية.

تعريف هذه الطريقة خاص بعض الشيء، لأن الوسيط الذي تستقبله الطريقة يأتي بعد علامة =. وتستخدم طرق أخرى خاصة عديدة في Crystal هذا التركيب، مثل طريقة +.

وكما في ماكرو getter، عندما تريد تحديث قيمة متغير نسخة بعد تعريف setter، يمكنك استدعاء الطريقة التي عرّفها ماكرو setter.

# 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

property

property ماكرو يعرّف كلاً من getter وsetter لمتغير نسخة.

class Person
  @name : String
  @age : Int32

  property name, :age
end

التعليمات

في هذا التمرين ستقوم بنمذجة آلة وزن.

1. إنشاء حالة أولية لآلة الوزن

عند تهيئتها، ينبغي أن تعتمد آلة الوزن على إعدادات المصنع، وهي تختلف باختلاف المكان الذي تُباع فيه الآلة. ولذلك ينبغي أن يكون بالإمكان تهيئة الآلة بدقة معيّنة، وبما يحدد ما إذا كانت تستخدم النظام المتري أم الإمبراطوري.

نفّذ الطريقة 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 لتتعلّم وتتقن Crystal عبر 26 مفهومًا142 تمرينًا، وإرشاد بشري حقيقي، وكل ذلك مجانًا.