مسیرها
/
Crystal
Crystal
/
تمرین‌ها
/
آبمیوه‌گیری یوهانس
آبمیوه‌گیری یوهانس

آبمیوه‌گیری یوهانس

تمرین یادگیری

مقدمه

کلاس‌ها مفهوم محوری در برنامه‌نویسی شیءگرا هستند. در Crystal همه‌چیز یک شیء است، هر شیء یک نوع دارد و می‌تواند به برخی متدها پاسخ دهد. کلاس‌ها نقشه‌ی ساخت اشیاء هستند و مقادیر اولیه‌ی وضعیت، مانند متغیرها، و پیاده‌سازی‌های رفتار، مانند متدها، را فراهم می‌کنند. اشیاء نمونه‌های کلاس‌اند که همه‌ی متغیرهای نمونه و وضعیت‌ها را نگه می‌دارند.

تعریف کلاس

کلاس با کلیدواژه‌ی class تعریف می‌شود و پس از آن، اسم کلاس به شکل UpperCamelCase نوشته می‌شود.

class Account
end

ساختن یک نمونه

برای ساختن یک نمونه از یک کلاس، اسم کلاس را با متد new فراخوانی کنید.

class Account
end

account = Account.new

در مثال بالا، متغیر account یک نمونه از کلاس Account است.

هنگام ساختن یک نمونه، یک متد ویژه به اسم initialize نقش سازنده را ایفا می‌کند. این متد زمانی فراخوانی می‌شود که یک نمونه ساخته می‌شود. سازنده به شما اجازه می‌دهد وضعیت اولیه‌ی نمونه را تعیین کنید. متد initialize می‌تواند آرگومان بگیرد؛ آرگومان‌ها هنگام ساختن نمونه پاس داده می‌شوند.

class Account
  def initialize(number)
    5 + number # => 9
  end
end

Account.new(4)
Note

متد initialize نمی‌تواند به‌صورت دستی مقداری برگرداند؛ در عوض، new نمونه‌ی تازه‌ساخته‌شده را برمی‌گرداند.

class Account
  def initialize(number)
    5 + number
  end
end

Account.new(4)
# => #<Account:0x7f5dc33dcea0>

متدهای نمونه

متد نمونه متدی است که در دسترس یک نمونه از کلاس قرار دارد و می‌توان آن را روی آن نمونه فراخوانی کرد. متدهای نمونه با کلیدواژه‌ی def و پس از آن اسم متد تعریف می‌شوند. این متدها داخل تعریف کلاس تعریف می‌شوند.

class Account
  def balance
    100
  end
end

account = Account.new
account.balance # => 100

متغیرهای نمونه

متغیرهای نمونه متغیرهایی هستند که در همه‌ی متدهای نمونه در دسترس‌اند. برای دسترسی به یک متغیر نمونه باید یک متد نمونه تعریف کنید. می‌توان آن‌ها را در متد initialize مقداردهی اولیه کرد. این متغیرها با پیشوند @ تعریف می‌شوند.

class Account
  def initialize
    @balance = 100
  end

  def balance
    @balance
  end
end

account = Account.new
account.balance
# => 100

متغیرهای نمونه را می‌توان داخل تعریف کلاس هم تعریف کرد.

class Account
  @age = 0
end

متغیرهای نمونه همراه با مقداردهی اولیه

متغیرهای نمونه را می‌توان با آرگومانی که به متد initialize پاس داده می‌شود مقداردهی اولیه کرد. از آنجا که Crystal نمی‌تواند نوع آرگومان به‌کاررفته هنگام مقداردهی اولیه را استنتاج کند، باید مشخص شود. اگر می‌خواهید درباره‌ی این موضوع بیشتر بخوانید، می‌توانید این را بخوانید: type-inference. برای مشخص کردن نوع متغیر می‌توانید از نماد : و پس از آن نوع استفاده کنید. برای نمونه، اگر می‌خواهید یک متغیر نمونه به اسم balance از نوع Int32 بسازید، می‌توانید این کار را بکنید: @balance : Int32. یا اگر می‌خواهید یک متغیر نمونه به اسم raining از نوع Bool بسازید، می‌توانید این کار را بکنید: @raining : Bool.

برای پیاده‌سازی این کار چند راه وجود دارد؛ یکی اینکه در متد initialize آرگومان را همراه با نوعش اعلام کنید و سپس متغیر نمونه را به آرگومان نسبت دهید، مانند مثال زیر:

class Account
  def initialize(balance : Int32)
    @balance = balance
  end

  def balance
    @balance
  end
end

account = Account.new(1)
account_2 = Account.new(5)

account.balance
# => 1

account_2.balance
# => 5

راه دیگر این است که نوع متغیر نمونه را در تعریف کلاس، به شکل @<variable> : <Type> اعلام کنید، مانند مثال زیر:

class Weather

  @raining : Bool

  def initialize(raining)
    @raining = raining
  end

  def raining
    @raining
  end
end

weather = Weather.new(true)
weather.raining
# => true

تغییر متغیرهای نمونه

متدها می‌توانند متغیرهای نمونه را تغییر دهند. این متدها را می‌توان روی نمونه‌ی کلاس فراخوانی کرد. وقتی متدی یک متغیر نمونه را تغییر می‌دهد، آن تغییر فقط در همان نمونه از کلاسی که متد را روی آن فراخوانی کرده‌اید در دسترس است.

class Account
  def initialize(balance : Int32)
    @balance = balance
  end

  def withdraw(amount)
    @balance -= amount
  end

  def balance
    @balance
  end
end

account = Account.new(10)
account_2 = Account.new(10)
account.balance
# => 10

account_2.balance
# => 10

account.withdraw(5)
account.balance
# => 5

account_2.balance
# => 10

متدهای کلاس

متدهای کلاس متدهایی هستند که برای یک کلاس تعریف می‌شوند، نه برای نمونه‌های آن. این متدها راهی برای ساختن متدهایی فراهم می‌کنند که به وضعیت نمونه وابسته نیستند. متدهای کلاس با کلیدواژه‌ی def و پس از آن self.<method name> تعریف می‌شوند. self ارجاعی است به فضای نامی که self از آن فراخوانی می‌شود. در این مورد، به کلاس Account اشاره دارد. این دقیقاً همان چیزی است که اگر Account. را می‌نوشتید، اما self. روش ترجیحی است.

class Account
  def self.balance
    100
  end
end

Account.balance
# => 100

دستورالعمل‌ها

دوستتان یوهانس عاشق ساختن سخت‌افزارهای دست‌ساز (خودتان انجام دهید) است. او به‌تازگی یک آبمیوه‌گیری ساخته است و یوهانس خیلی برایش هیجان‌زده است. هدف یوهانس این است که بتواند هر روز صبح آبمیوه‌ی تازه درست کند.

آبمیوه‌گیری یوهانس امکانات پیشرفته‌ی زیادی دارد. مثلاً یک سیستم اندازه‌گیری داخلی که می‌تواند به شما بگوید چقدر آبمیوه در لیوان است. یک تایمر هم دارد که به شما می‌گوید دستگاه چه مدت است کار می‌کند.

یوهانس در برنامه‌نویسی بهترین نیست، اما می‌خواهد برنامه‌ای بنویسد تا دستگاه را کنترل کند. به همین دلیل از شما خواسته است که به او کمک کنید.

1. چراغ Debug

دستگاه یک چراغ Debug دارد؛ مکانیزم آن ساده است: اگر دستگاه برق داشته باشد، چراغ Debug روشن است. برنامه فقط زمانی اجرا می‌شود که چراغ Debug روشن باشد.

این متد باید یک متد کلاس به نام JuiceMaker باشد.

متد کلاس JuiceMaker.debug_light_on? را تعریف کنید که true برمی‌گرداند.

JuiceMaker.debug_light_on?
#=> true

2. مقداردهی اولیه‌ی دستگاه

وقتی دستگاه روشن می‌شود، باید نمونه‌ای از کلاسی به نام JuiceMaker ساخته شود. دستگاه باید یک حالت مقداردهی‌شده داشته باشد. حالت مقداردهی‌شده باید اطلاعات زیر را نگه دارد:

  1. این که دستگاه در حال کار است یا نه. این مقدار وقتی دستگاه روشن می‌شود باید همیشه false باشد.
  2. مقدار آبمیوه در لیوان؛ این یک حسگر خواهد بود که مقدار آبمیوه در لیوان را اندازه می‌گیرد.

حالت مقداردهی‌شده را تعریف کنید، که مقدار آبمیوه در لیوان را به عنوان پارامتر می‌گیرد، و آن را بسازید. حالت مقداردهی‌شده باید یک متغیر نمونه‌ای @running داشته باشد که روی false تنظیم شده است و یک متغیر نمونه‌ای @fluid که بر اساس آرگومانی که هنگام مقداردهی اولیه‌ی کلاس داده می‌شود تعیین می‌شود.

JuiceMaker.new(5)
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=5>

3. روشن کردن دستگاه

دستگاه را می‌توان روشن و خاموش کرد. باید متدی برای روشن کردن دستگاه تعریف کنید. وقتی دستگاه روشن می‌شود، حالت کار باید روی true تنظیم شود.

متد JuiceMaker#start را تعریف کنید که دستگاه را روشن می‌کند.

juice_maker = JuiceMaker.new(5)
juice_maker.start

juice_maker
#=> #<JuiceMaker:0x10f0b8 @running=true, @fluid=5>

4. وضعیت دستگاه

دستگاه باید بتواند وضعیت خودش را به شما بگوید. اگر دستگاه در حال کار باشد باید true برگرداند و اگر در حال کار نباشد باید false برگرداند.

متد JuiceMaker#running? را تعریف کنید که وضعیت دستگاه را برمی‌گرداند.

juice_maker = JuiceMaker.new(5)
juice_maker.start

juice_maker.running?
#=> true

5. افزودن آبمیوه

دستگاه می‌تواند به لیوان آبمیوه اضافه کند. دستگاه می‌تواند بگوید چقدر آبمیوه به لیوان اضافه شده است. دستگاه برای دانستن مقدار آبمیوه در لیوان پس از افزودن آبمیوه به کمک نیاز دارد.

متد JuiceMaker#add_fluid را تعریف کنید، که مقدار آبمیوه‌ی افزوده‌شده را به عنوان پارامتر می‌گیرد و مقدار آبمیوه در لیوان را به‌روزرسانی می‌کند.

juice_maker = JuiceMaker.new(5)
juice_maker.add_fluid(5)

juice_maker
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=10>

6. خاموش کردن دستگاه

دستگاه را می‌توان روشن و خاموش کرد. باید متدی برای خاموش کردن دستگاه تعریف کنید. این متد فقط زمانی فراخوانی می‌شود که دستگاه در حال کار باشد. وقتی دستگاه خاموش می‌شود، حالت کار باید روی false تنظیم شود. دستگاه همچنین برای تعیین مقدار آبمیوه در لیوان پس از خاموش شدن به کمک نیاز دارد. دستگاه در هر دقیقه پنج واحد آبمیوه مصرف می‌کند.

متد JuiceMaker#stop را تعریف کنید که تعداد دقیقه‌هایی را که دستگاه کار کرده است به عنوان پارامتر می‌گیرد و مقدار آبمیوه در لیوان را پس از خاموش شدن دستگاه برمی‌گرداند.

juice_maker = JuiceMaker.new(5)

juice_maker.start
juice_maker
#=> <JuiceMaker:0x10f0b8 @running=true, @fluid=5>

juice_maker.stop(1)
#=> #<JuiceMaker:0x10f0b8 @running=false, @fluid=0>
ویرایش از طریق GitHub این لینک در پنجره یا زبانه‌ی جدیدی باز می‌شود
Crystal Exercism

آماده‌اید آبمیوه‌گیری یوهانس را شروع کنید؟

در Exercism ثبت‌نام کنید تا Crystal را همراه با 26 مفهوم142 تمرین و مربی‌گری انسانی واقعی یاد بگیرید و در آن استاد شوید، همه‌ی این‌ها رایگان.