【问题标题】:How to make an object with a default value with it's not passed to the class?如何使具有默认值的对象不传递给类?
【发布时间】:2020-02-24 05:37:58
【问题描述】:

当没有变量类别的输入时,我试图在 Produto 类中创建一个默认值为“Geral”的对象,但我在理解这个挑战的问题时遇到了一些麻烦,我已经一直在寻找关于面向对象的更深入的课程,但不知道我应该改变什么才能让它工作,如果这是一个愚蠢的问题,我真的很抱歉。

categoria.rb

require 'produto'
class Categoria 
  attr_accessor :nome
  def initialize(nome: 'Geral')
    @nome = nome
  end
end
class Produto 
  attr_accessor :nome, :categoria, :preco, :estoque
  def initialize(nome: 'Sem nome', categoria: categoria , preco: '0', estoque: '0')
    @nome = nome
    @preco = preco
    @categoria = categoria
    @estoque = estoque
  end

  def adiciona_estoque(quantidade)
    @estoque += quantidade
  end

  def remove_estoque(quantidade)
    @estoque -= quantidade
  end
end
spec.rb

  it "deveria criar um objeto de categoria Geral por padrão" do
    nome = 'Teclado'
    preco = 100
    estoque = 3
    produto = Produto.new(nome: nome, preco: preco, estoque: estoque)

    expect(produto.nome).to eq 'Teclado'
    expect(produto.categoria.nome).to eq 'Geral'
    expect(produto.preco).to eq 100
    expect(produto.estoque).to eq 3
  end

rspec 输出


Produto deveria criar um objeto de categoria Geral por padrão
    Failure/Error: expect(produto.categoria.nome).to eq 'Geral'

    NoMethodError:
      undefined method `nome' for nil:NilClass
    # ./spec/1_produto_spec.rb:25:in `block (2 levels) in <top (required)>'


【问题讨论】:

  • @categoria = categoria => @categoria = categoria || Categoria.new

标签: ruby class object


【解决方案1】:

简短回答: 你需要改变

def initialize(nome: 'Sem nome', categoria: categoria , preco: '0', estoque: '0')
  @nome = nome
  @preco = preco
  @categoria = categoria
  @estoque = estoque
end

def initialize(nome: 'Sem nome', categoria: categoria , preco: '0', estoque: '0')
  @nome = nome
  @preco = preco
  @categoria = categoria || Categoria.new
  @estoque = estoque
end

长答案: attr_accessor :categoria 相同的问题

def categoria
  @categoria
end

def categoria=(val)
  @categoria = val
end

这意味着当你没有在Produto.new 中设置categoria 时,它需要@categoria 等于nil

【解决方案2】:

如果您尝试在 Produto 的类定义中逐字运行代码,您会注意到输出

warning: circular argument reference - categoria

这是第一个线索。此外,您会注意到 Categoria#nome 是一个实例方法。这意味着您必须处理该类的实例才能成功调用该方法。

尝试修改您的 Produto 初始化参数,以确保您实际上默认为其提供 Categoria 的实例(而不是 categoria,除非您传入一个值,否则它将是 nil)。例如:

class Categoria
  ...
  def initialize(nome: 'Sem nome', categoria: Categoria.new , preco: '0', estoque: '0')
    @nome = nome
    @preco = preco
    @categoria = categoria
    @estoque = estoque
  end
  ...
end

进行更改后,您应该会看到(在您的测试块中)produto.categoria.nome 返回“Geral”。

【讨论】:

    猜你喜欢
    • 2012-03-23
    • 2011-04-15
    • 2014-07-12
    • 2018-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多