Object expected to be a kind of a Class

Here's what I need to do:

  1. I need this attribute "titular" to be a Cliente kind.

  2. In Conta.rb, in insert 'conta.titular.nome that is equal to titular'

I've tried using super(), making the class Cliente parent of Conta. But nothing worked and I'm totally lost. I can't imagine how one attribute from a class could be the kind of another one. I read lots of tutorials about inheritance but nothing came close from that. Hope someone could explain me this.

Conta.rb

class Conta 
  attr_accessor :titular, :limite, :saldo, :numero

  def initialize(numero, titular, saldo, limite)
    @numero = numero
    @titular = titular
    @saldo = saldo
    @limite = limite
  end

  def kind_of(klass)
    Cliente >= klass
  end

  def sacar(valor)
    return false if valor > (@saldo + @limite)

    @saldo -= valor
    true
  end

  def depositar(valor)
    @saldo += valor
  end

  def no_limite?
    @saldo < 0
  end

  def ==(conta)
      conta.titular == titular &&
      conta.limite == limite &&
      conta.saldo == saldo &&
      conta.numero == numero
  end

  def transfere(conta_destino, valor_transferencia)
    return false unless sacar(valor_transferencia)
    conta_destino.depositar(valor_transferencia)
  end
end

Spec

describe Conta do
#1.
  it "titular deveria ser um Cliente" do
    conta = Conta.new('2303-2', 'José da Silva', 1000.10, 500)

    expect(conta.titular).to be_a(Cliente)
  end

#2.
  it "deveria conseguir criar um objeto do tipo Conta" do
    numero = "2303-2"
    titular = "José da Silva"
    saldo = 1000.10
    limite = 500
    conta = Conta.new(numero, titular, saldo, limite)

    expect(conta.numero).to eq numero
    expect(conta.titular.nome).to eq titular
    expect(conta.limite).to eq limite
    expect(conta.saldo).to eq saldo
  end

Cliente.rb

class Cliente
    attr_accessor :nome, :sobrenome, :cpf, :nome_completo, :tratamento
    def initialize(nome, sobrenome, cpf)
        @nome = nome
        @sobrenome = sobrenome
        @cpf = cpf
    end

    def nome_completo
        if @tratamento.nil?
            return @nome_completo = @nome + ' ' + @sobrenome
        else
            return @nome_completo = @tratamento + ' ' + @nome + ' ' + @sobrenome
        end
    end
end

Error:

  1) Conta titular deveria ser um Cliente
     Failure/Error: expect(conta.titular).to be_a(Cliente)
       expected "José da Silva" to be a kind of Cliente
     # ./spec/conta_spec.rb:7:in `block (2 levels) in <top (required)>'

2) Conta deveria conseguir criar um objeto do tipo Conta
     Failure/Error: expect(conta.titular.nome).to eq titular

     NoMethodError:
       undefined method `nome' for "José da Silva":String
     # ./spec/conta_spec.rb:18:in `block (2 levels) in <top (required)>'

Upvotes: 1

Views: 153

Answers (1)

Sebasti&#225;n Palma
Sebasti&#225;n Palma

Reputation: 33420

You can create a new Cliente object and pass it as the titular argument defined in Conta:

conta = Conta.new('2303-2', Cliente.new('José da Silva', nil, nil), 1000.10, 500)
p conta.kind_of(Cliente) # true

You can modify your Conta class to delegate the method nome to titular:

require 'forwardable'

class Conta 
  extend Forwardable

  ...

  def kind_of(klass)
    titular.kind_of?(klass)
  end

  def_delegators :titular, :nome
end

p conta.nome # "José da Silva"

Also, you can redefine kind_of invoke kind_of? on titular using the klass argument received.

Upvotes: 3

Related Questions