Crystal نوعی به نام Nil دارد که تنها میتواند یک مقدار داشته باشد: nil.
از آن برای نشان دادن نبودِ مقدار استفاده میشود و شبیه به null یا None در زبانهای دیگر است.
مقدارهای Nil را میتوان از متدهای مختلفی برگرداند؛ برای نمونه String#[]? که اگر اندیس خارج از محدوده باشد nil برمیگرداند.
"foo"[10]? # => nil
Crystal چیزی دارد که به آن بررسی ارجاع پوچ میگویند؛ یعنی همهی نوعها بهطور پیشفرض نمیتوانند nil باشند.
یعنی نمیتوانید به یک متغیر nil نسبت دهید، مگر آنکه آن را صریحاً از نوع Nil اعلام کنید.
این هم به نوبهی خود یعنی اینکه کامپایلر بهطور خودکار ارجاعهای پوچ را بررسی میکند.
برای کار با مقدارهای nil میتوان رویکردهای متفاوتی در پیش گرفت.
nil یک مقدار کاذب است، همانطور که false هم چنین است.
یعنی در دستورها و جاهای دیگری که یک مقدار کاذب یا صادق انتظار میرود، با nil همانطور رفتار میشود که با false.
if nil
puts "nil is truthy"
else
puts "nil is falsey"
end
# => nil is falsey
یعنی اگر متغیری که میتواند nil باشد مقدارش nil باشد، شاخهی صادق اجرا نمیشود.
foo = "boo"[2]? # It is possible that foo is nil
if foo
p foo.class # => Char
end
Crystal متدی دارد که با آن میتوان بررسی کرد آیا یک مقدار nil است.
اسم آن nil? است و روی همهی اشیاء در دسترس است.
foo = "boo"[2]?
if foo.nil?
puts "foo is nil"
else
puts "foo is not nil"
end
وقتی فقط از خود مقدار در یک دستور if استفاده میکنید، ماجرا کمی فرق میکند؛ چون در مثالهای پیشین، هم false و هم nil کاذب به شمار میآمدند.
اینجا فقط nil کاذب به حساب میآید، چون اگر مقدار false بود دیگر nil نبود و در نتیجه صادق میشد.
سادهترین راه برای کار با مقدارهای nil این است که کاری کنید همان ابتدا هرگز nil نشوند.
عملگر or (||) بیشتر هنگام کار با Bools به کار میرود، اما اگر درست فهمیده شود، میتوان از آن برای کار با مقدارهای nil هم استفاده کرد.
عملگر or بررسی میکند که آیا مقدار اول صادق است؛ اگر نباشد، مقدار دوم به کار میرود.
این کار باعث میشود که اگر مقدار nil باشد، کاذب به حساب بیاید و در نتیجه مقدار دوم استفاده شود.
"foo"[10]? || "bar" # => "bar"
اعلیحضرت میزبان یک ضیافت شام در پایتخت اتحادیهی کالمار، کپنهاگ هستند. این بزرگترین مهمانی سال است و همهی اشراف دعوت شدهاند. اما شایعاتی در سراسر کشور پخش میشود که توطئهای برای مسموم کردن اعلیحضرت وجود دارد.
اعلیحضرت از شما، یابندهی زهر سلطنتی، خواستهاند تا بفهمید آیا غذایی یا نوشیدنیای مسموم است. اعلیحضرت قصد دارند فقط Mushroom pasties را بهعنوان غذا سرو کنند، اما برای نوشیدنیها، انواع مختلفی وجود دارد.
اگر غذا همان چیزی نباشد که اعلیحضرت سفارش دادهاند، احتمال زیادی هست که مسموم باشد. اگر غذا همان چیزی نباشد که اعلیحضرت سفارش دادهاند، باید دور انداخته شود.
متد check_food? را پیادهسازی کنید، که آرگومان food را میگیرد و اسم غذا را بهصورت یک String نگه میدارد.
متد باید اگر غذا Mushroom pasties بود، غذا را برگرداند؛ در غیر این صورت، باید nil را برگرداند.
CastleDinner.check_food?("Mushroom pasties")
# => "Mushroom pasties"
CastleDinner.check_food?("Bread")
# => nil
ممکن است نوشیدنی مسموم باشد، اما تشخیص آن کمی دشوارتر است.
نوشیدنی مسموم است اگر اسم آن حرف i را نداشته باشد؛ بزرگ یا کوچک بودن حرف مهم نیست.
اگر نوشیدنی مسموم باشد، باید دور انداخته شود.
متد check_drink? را پیادهسازی کنید، که آرگومان drink را میگیرد و اسم نوشیدنی را بهصورت یک String نگه میدارد.
متد باید اگر نوشیدنی مسموم نبود، نوشیدنی را برگرداند؛ در غیر این صورت، باید nil را برگرداند.
CastleDinner.check_drink?("Apple juice")
# => "Apple juice"
CastleDinner.check_drink?("Tea")
# => nil
اعلیحضرت نمیخواهند مهمانهایشان را دربارهی زهر در غذایشان نگران کنند. بنابراین، اگر نوشیدنی مسموم باشد، باید با یک نوشیدنی جدید، بهطور مشخص Apple juice، جایگزین شود.
متد replace_drink را پیادهسازی کنید، که آرگومان drink را میگیرد و اسم نوشیدنی را بهصورت یک String نگه میدارد.
متد باید اگر نوشیدنی مسموم نبود، نوشیدنی را برگرداند؛ در غیر این صورت، باید "Apple juice" را برگرداند.
CastleDinner.replace_drink("Orange juice")
# => "Orange juice"
CastleDinner.replace_drink("Tea")
# => "Apple juice"