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、网络之类的内容。它还提供了一些实用的功能,让你的代码更易于使用。
在使用不属于核心库的类时,比如你自己写在其他文件里的代码、来自标准库的类,或者外部的依赖,我们需要先用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