الیکسیر از Behaviourها استفاده میکند تا رابطهای عمومیِ مشترکی فراهم کند و در همان حال به هر ماژولی که آنها را پیادهسازی میکند امکان دهد پیادهسازی اختصاصی خودش را داشته باشد. یکی از نمونههای رایج این کار، Access Behaviour است.
Access Behaviour یک رابط مشترک برای بازیابی داده از یک ساختار دادهی مبتنی بر کلید فراهم میکند. Access Behaviour برای mapها و keyword listها پیادهسازی شده است، اما بیایید کاربردش را برای mapها ببینیم تا با آن آشنا شوید. Access Behaviour مشخص میکند که وقتی یک map دارید، میتوانید بعد از آن «کروشه» بگذارید و سپس با استفاده از کلید، مقدار مرتبط با آن کلید را بازیابی کنید.
# Suppose we have these two maps defined (note the difference in the key type)
my_map = %{key: "my value"}
your_map = %{"key" => "your value"}
# Obtain the value using the Access Behaviour
my_map[:key] == "my value"
your_map[:key] == nil
your_map["key"] == "your value"
اگر کلید در ساختار داده وجود نداشته باشد، nil برگردانده میشود. این میتواند باعث بروز رفتارهای ناخواسته شود، چون خطایی ایجاد نمیکند. توجه کنید که خود nil هم Access Behaviour را پیادهسازی میکند و برای هر کلیدی همیشه nil را برمیگرداند.
شما با یک تیم توسعهی وب کار میکنید که وبسایتی برای یک تیم بسکتبال محلی نگهداری میکند. تیم توسعهی وب با Elixir آشنایی کمتری دارد و میخواهد تابعی داشته باشد که بتواند دادهها را از مجموعههای تودرتوی «نگاشت» استخراج کند تا توسعه سریعتر پیش برود.
تابع extract_from_path/2 را طوری پیادهسازی کنید که دو آرگومان بگیرد:
data: یک ساختار نگاشت تودرتو که دادههای مربوط به تیم بسکتبال را در خود دارد.path: رشتهای متشکل از کلیدهای جداشده با نقطه، برای به دست آوردن مقدار متناظر با آخرین کلید.اگر مقدار یا کلید در هیچ نقطهای از مسیر وجود نداشته باشد، باید nil برگردانده شود
data = %{
"team_mascot" => %{
"animal" => "bear",
"actor" => %{
"first_name" => "Noel"
}
}
}
BasketballWebsite.extract_from_path(data, "team_mascot.animal")
# => "bear"
BasketballWebsite.extract_from_path(data, "team_mascot.colors")
# => nil
هنگام پیادهسازی این تابع از Access Behaviour استفاده کنید.
برای کار با ساختار نگاشت تودرتو از هیچیک از توابع ماژول Map یا Kernel استفاده نکنید.
همکارتان که در حال بازبینی کد شماست، از تابعی در ماژول Kernel به شما میگوید که کارش بسیار شبیه پیادهسازی شماست.
تابع get_in_path/2 را طوری پیادهسازی کنید که از این تابع ماژول Kernel استفاده کند.
آرگومانهای مورد انتظار همانند بخش ۱ هستند.
BasketballWebsite.get_in_path(data, "team_mascot.actor.first_name")
# => "Noel"