OpenStruct讓你輕鬆地從 Hash 建立物件。不必透過 Hash 的鍵來存取,OpenStruct讓我們改用方法來存取和設定值。
attributes = { name: "Jeremy Walker", age: 21, location: "Nomadic" }
person = OpenStruct.new(attributes)
person.name
#=> Jeremy Walker
person.location
#=> Nomadic
# Update the age
person.age = 35
# It sets correctly
person.age
#=> 35
這個做法還有一個好處:使用區塊語法時,我們可以利用一個捷徑。當區塊只呼叫單一方法時,你可以用&:加上方法名稱來取代整個區塊。例如下面這兩行是同義的:
people.sum { |person| person.age }
people.sum(&:age)
你在先前練習中看過的所有類別,都屬於 Ruby 的核心函式庫。
OpenStruct 是 Ruby 標準函式庫(常簡稱為「stdlib」)的一部分,這是一組用來處理日期、JSON、網路等項目的類別。它也提供一些實用的功能,讓你的程式碼更容易處理。
當你使用的類別不是來自核心函式庫時(例如放在其他檔案裡你自己的程式碼、來自 stdlib 的類別,或外部相依性),就必須先用require方法將它們匯入,才能使用。例如:
require 'ostruct'
person = OpenStruct.new(name: "Jeremy Walker")
# ...
你將繼續開發之前建立的庫存管理系統。自從認識了OpenStruct和區塊簡寫之後,你決定稍微重構一下程式碼。這次不再把項目存成雜湊,而是要運用你新學到的技巧。
你想要繼續取得庫存項目的陣列,但這次它們應該是可以在上面呼叫方法的物件。
inventory = BoutiqueInventory.new([
{price: 65.00, name: "Maxi Brown Dress", quantity_by_size: {s: 3, m: 7, l: 8, xl: 4}},
{price: 50.00, name: "Red Short Skirt", quantity_by_size: {}},
{price: 29.99, name: "Black Short Skirt", quantity_by_size: {s: 1, xl: 4}},
{price: 20.00, name: "Bamboo Socks Cats", quantity_by_size: {s: 7, m: 2}}
])
inventory.items.first.name
# => "Maxi Brown Dress"
inventory.items.first.price
# => 65
inventory.items.size
# => 4
item_names
重構 item_names,改用你新學到的區塊簡寫,而不要使用雜湊。
提醒你,這個方法應該回傳:
BoutiqueInventory.new([
{price: 65.00, name: "Maxi Brown Dress", quantity_by_size: {s: 3, m: 7, l: 8, xl: 4}},
{price: 50.00, name: "Red Short Skirt", quantity_by_size: {}},
{price: 29.99, name: "Black Short Skirt", quantity_by_size: {s: 1, xl: 4}},
{price: 20.00, name: "Bamboo Socks Cats", quantity_by_size: {s: 7, m: 2}}
]).item_names
# => ["Bamboo Socks Cats", "Black Short Skirt", "Maxi Brown Dress", "Red Short Skirt"]
total_stock
重構 total_stock,改用 OpenStruct 的方法,而不要參照雜湊。
提醒你,這個方法應該回傳:
BoutiqueInventory.new([
{price: 65.00, name: "Maxi Brown Dress", quantity_by_size: {s: 3, m: 7, l: 8, xl: 4}},
{price: 50.00, name: "Red Short Skirt", quantity_by_size: {}},
{price: 29.99, name: "Black Short Skirt", quantity_by_size: {s: 1, xl: 4}},
{price: 20.00, name: "Bamboo Socks Cats", quantity_by_size: {s: 7, m: 2}}
]).total_stock
# => 36