红宝石工厂方法返回的时候,它被称为NoMethodError。发生了什么?

问题描述 投票:0回答:2

我想一个工厂方法融入这个帝国到公制转换器。我可以把它独立工作,但是当它通过成分的哈希迭代它带来了一个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
ruby methods factory
2个回答
1
投票

您可以使用Gramulator.for(@amount, @unit),但Gramulator.for预计unit, amount

这将导致@units[unit]返回零,因为你给它"3.5",而不是在单位的说法"cups"


0
投票

当你调用@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可以提供给你。

© www.soinside.com 2019 - 2024. All rights reserved.