我想一个工厂方法融入这个帝国到公制转换器。我可以把它独立工作,但是当它通过成分的哈希迭代它带来了一个NoMethodError
。我做错了什么?
我已经运行通过工厂的独立实例变量没有问题:
@item = "cups"
@number = 89.2
Gramulator.for(@number, @item) # => 828.0300000000001
我已经证实,它与投入正常工作。我甚至有@dough.unit
和@dough.amount
成功运行:
Gramulator for(@dough.amount, @dough.unit) # => 828.0300000000001
但是,当我点它通过迭代方法本身,@dough.gramulate
不起作用。
class Unit
def initialize(amount)
@amount = amount
end
def calculate
@amount.to_f
end
end
class Cup < Unit
def calculate
(super * 236.58)
end
end
class Recipe
attr_accessor :amount
attr_reader :name, :unit
def initialize(ingredient_hash)
@ingredient_hash = ingredient_hash
end
def gramulate
puts "CONVERTED TO GRAMS:"
@ingredient_hash.each do |name, quantity|
quantity_array = quantity.split
@name = name
@amount = quantity_array[0].to_f
@unit = quantity_array[1]
Gramulator.for(@amount, @unit)
puts "#{@name}: #{@amount} grams"
end
end
end
module Gramulator
@units = {
"cups" => Cup
# <other measurements>
}
def self.for(unit, amount)
(@units[unit]).new(amount).calculate
end
end
@dough = Recipe.new({
bread_flour: "3.5 cups"
# <other ingredients>
})
预期结果:
CONVERTED TO GRAMS:
bread_flour: 828.0300000000001 grams
实际结果:
CONVERTED TO GRAMS:
NoMethodError: undefined method 'new' for nil:NilClass
您可以使用Gramulator.for(@amount, @unit)
,但Gramulator.for
预计unit, amount
。
这将导致@units[unit]
返回零,因为你给它"3.5"
,而不是在单位的说法"cups"
。
当你调用@units[unit]
你nil
,因为它上面你调用单位和金额倒置for
。见Gramulator.for(@amount, @unit)
。该signutre是def self.for(unit, amount)
。
话虽这么说......也许我是过于简单化了,但我觉得你的代码可能会减少。
下面我重写它可能被设置为一个可执行文件(用chmod +x
)的脚本并运行为./gramulator.rb。
如果你需要在一个更大的项目将这一随意跳过第一个和最后两行。
#!/usr/bin/env ruby
class Gramulator
UNITS = { "cups" => 236.58 }
def self.for(unit, amount)
amount.to_f * UNITS[unit]
end
end
class Recipe
def initialize(ingredients)
@ingredients = ingredients
end
def gramulate
puts "CONVERTED TO GRAMS"
@ingredients.each do |name, quantity|
amount, unit = quantity.split
puts "%s: %.2f grams" % [name, amount]
Gramulator.for(unit, amount)
end
end
end
dough = Recipe.new({ bread_flour: "3.5 cups" })
dough.gramulate
请注意,puts
返回nil
,因此是一个好习惯,避免使用它在一个循环/迭代方法矿石的结束。这里,我们使用each
,这是很好的,因为你可能不感兴趣,重用ingredients.each {...}
结果。
然而,在Ruby中,你可以有其他有用的Enumerable
方法,如地图更加有乐趣,检测等他们返回的东西比你对迭代所以他们的循环的最后一行必须是原始集合不同的“事”。我强烈建议你看看他们。
对不起,是长期的,它只是帮你觉得什么是Ruby可以提供给你。