Undefined method '' in Ruby

0

I have been commissioned to make a version of the Monopoly game called Qytetet. Currently I have 4 Ruby files, 2 of them are classes and the other 2 are modules (one of them contains another class). I explain a little,

  • Surprise Class : It has 3 instance attributes; @text, @type and @valor. Contains the initialize method and the to_s method.
  • Qytetet class : It has the instance attribute @mazo. Also a class method that initializes @mazo with the corresponding elements: a description (@text), a value (@valor) and a type (@type).
  • Modulo TipoSorpresa : Contains the types of surprise.
  • Module-Class PruebaQytetet : Contains class attribute @@ game, 3 class methods to perform some operations and the main class method, which seeks to print the results of the 3 operations (and obviously create a new one) mallet and others).

The problem is that when running on NetBeans, I get the following error:

  

NoMethodError: undefined method '< <' for nil: NilClass

The error occurs on line 15 of qytetet.rb, just by assigning the first element to the @mazo array. I leave you with the corresponding codes.

sorpresa.rb

    class Sorpresa

  def initialize(nuevo_texto, nuevo_tipo, nuevo_valor)
    @texto = nuevo_texto
    @tipo = nuevo_tipo
    @valor = nuevo_valor
  end

  attr_reader :texto, :tipo, :valor

  def to_s
    puts "Texto: #{@texto} \n Valor: #{@valor} \n Tipo: #{@tipo}"
  end
end

qytetet.rb

require_relative "tipo_sorpresa"

class Qytetet

  def initialize
    @mazo = Array.new
  end

  attr_reader :mazo

  def self.inicializar_cartas_sorpresa
    @mazo<< Sorpresa.new("Te han pillado saqueando las arcas públicas del estado, vas a la cárcel.", 9, TipoSorpresa::IRACASILLA)
    @mazo<< Sorpresa.new("No sabemos si estabas cerca de la casilla inicial o no, pero ahora lo vas a estar.", 1, TipoSorpresa::IRACASILLA)
    @mazo<< Sorpresa.new("¿Eres supersticioso?", 13, TipoSorpresa::IRACASILLA)
    @mazo<< Sorpresa.new("Resulta que un funcionario de la cárcel es amigo tuyo. De casualidades está hecha la vida. Sales de la cárcel.", 0, TipoSorpresa::SALIRCARCEL)
    @mazo<< Sorpresa.new("Tus rivales te odian tanto que les obligamos a que te den lo que lleven suelto en la cartera.", 200, TipoSorpresa::PORJUGADOR)
    @mazo<< Sorpresa.new("Parece que te está gustando el juego, por eso tendrás que recompensar a tus rivales.", -300, TipoSorpresa::PORJUGADOR)
    @mazo<< Sorpresa.new("¡Enhorabuena! Te ha tocado la lotería, pero la agencia tributaria se va a quedar casi todo.", 250, TipoSorpresa::PAGARCOBRAR)
    @mazo<< Sorpresa.new("Vamos a jugar a algo, tú me das algo de dinero y yo no te doy nada. ¿Qué te parece?", -250, TipoSorpresa::PAGARCOBRAR)
    @mazo<< Sorpresa.new("Vaya, esta sorpresa parece que te va a quitar algo de dinero por los hoteles y casas de tus rivales, siempre y cuando tú estés de acuerdo... o no.", -150, TipoSorpresa::PORCASAHOTEL)
    @mazo<< Sorpresa.new("Estás de suerte. Tus propiedades acaban de evadir impuestos y te dan algo más de dinero extra.", 200, TipoSorpresa::PORCASAHOTEL)
  end
end

tipo_sorpresa.rb

module TipoSorpresa
    PAGARCOBRAR = :Pagar_cobrar
    IRACASILLA = :Ir_casilla
    PORCASAHOTEL = :Por_casahotel
    PORJUGADOR = :Por_jugador
    SALIRCARCEL = :Salir_carcel
end

prueba_qytetet.rb

require_relative "sorpresa"
require_relative "qytetet"

module ModeloQytetet
  class PruebaQytetet
    @@juego = Array.new

    def self.mayor_que_cero
      mayor_cero = Array.new
      for s in @@juego.mazo
        if(mazo.valor > 0)
          mayor_cero.mazo = s
        end
      end
      return mayor_cero
    end

    def self.tipo_casilla
      tipo_casilla = Array.new
      for s in @@juego.mazo
        if(mazo.tipo == :Ir_casilla)
          tipo_casilla.mazo = s
        end
      end
      return tipo_casilla
    end

    def self.tipo_sorpresa(sorpresa)
      tipo_sorpresa = Array.new
      for s in TipoSorpresa::constants
        if(mazo.tipo == sorpresa)
          tipo_sorpresa = s
        end
      end
      return tipo_sorpresa
    end

    def self.main
      Qytetet.inicializar_cartas_sorpresa

      PruebaQytetet.mayor_que_cero
      PruebaQytetet.tipo_casilla
      PruebaQytetet.tipo_sorpresa
    end
  end

  PruebaQytetet.main
end

I would appreciate a little help, I do not understand that error at all. I think it has to do with syntax @@ mallet < < [...], but that's what they've told me to do. Thanks in advance.

    
asked by d3vcho 26.09.2018 в 16:30
source

1 answer

0

The problem is that the self.inicializar_cartas_sorpresa method is a method of the class , not of an instance of the class (i.e. object). At the moment of executing Qytetet.inicializar_cartas_sorpresa the variable @mazo has not been initialized (the method initialize is executed only when creating a new object with new ), therefore its value is nil , which does not have the << method.

One option to correct this error is that your method is instance , which you can do by removing self :

class Qytetet
  def initialize
    @mazo = Array.new
  end

  attr_reader :mazo

  def inicializar_cartas_sorpresa
    # ...
  end
end

And, in PruebaQytetet.main create an object Qytetet and then call the method:

module ModeloQytetet
  class PruebaQytetet
    # ...

    def self.main
      qytetet = Qytetet.new
      qytetet.initializar_cartas_sorpresa

      PruebaQytetet.mayor_que_cero
      PruebaQytetet.tipo_casilla
      PruebaQytetet.tipo_sorpresa
    end
  end

  PruebaQytetet.main
end

Still correcting the previous error your code will fail since I see several errors, being @@juego = Array.new the one that stands out the most; this will generate an error because then you call the mazo method on this variable which, being an array, does not have that method. I imagine that what you are looking for is that in @@juego you have the mazo generated with the class Qytetet , which you can achieve in the following way:

module ModeloQytetet
  class PruebaQytetet
    @@juego = Qytetet.new

    # ...

    def self.main
      @@juego = Qytetet.new
      @@juego.inicializar_cartas_sorpresa

      PruebaQytetet.mayor_que_cero
      PruebaQytetet.tipo_casilla
      PruebaQytetet.tipo_sorpresa
    end
  end

  PruebaQytetet.main
end

Even making the suggested correction, you will still have more errors because there are variables (e.g. mazo ) that you have not initialized but use, for example in this passage:

def self.mayor_que_cero
  mayor_cero = Array.new

  for s in @@juego.mazo
    if(mazo.valor > 0)     # esta línea te generará error ('mazo' no existe)
      mayor_cero.mazo = s  # esta línea te generará error (método 'mazo' no existe)
    end
  end
  return mayor_cero
end

To solve the first error, I suggest you use the each method; to solve the second you can create a new object Qytetet instead of an array in the variable mayor_cero ; for example:

def self.mayor_que_cero
  mayor_cero = Qytetet.new

  @@juego.mazo.each do |sorpresa|
    if(sorpresa.valor > 0)
      mayor_cero.mazo << sorpresa
    end
  end

  return mayor_cero
end

This code snippet will not throw errors, but I'm not sure if it respects the logic / rules of the game; This is just an example so you can see the type of errors in your code. In fact you will have to modify your code more because, even applying everything suggested here, you will still have more errors.

This answer will solve the error you show in your question, but I hope it will also help you to give you a little more direction to finish your program.

    
answered by 26.09.2018 / 17:23
source