Doubt regarding the || = operator of ruby

2

Hello I'm still starting in ruby, and I have a question regarding the following code

Main.rb

web_design = Livro.new "Ruby", "X", "9428", 56.40, :web_design
android_dev = Livro.new "Java", "Y", "9385", 78.9, :android_dev
game_dev = Livro.new "Unity", "Z", "9420", 67.5, :game_dev

biblioteca = Biblioteca.new

biblioteca.adiciona web_design
biblioteca.adiciona android_dev
biblioteca.adiciona game_dev

for categoria,livros in biblioteca.livros do
    p categoria
    for livro in livros do
        p livro.preco
    end
end

Library.rb

class Biblioteca

    attr_reader :livros

    def initialize
        @livros = []
    end

    def adiciona(livro)
        @livros[livro.categoria] ||= [] 
        @livros[livro.categoria] << livro
    end

    def livros
        @livros.values.flatten
    end
end

I looked a bit about the error, and it would be due to the fact that I'm treating an array as a hash.

def adiciona(livro)
    @livros[livro.categoria] ||= [] 
    @livros[livro.categoria] << livro
end

In addition to this section above indicate the error, to be quite frank its purpose has not been very clear.

Thank you in advance.

    
asked by anonymous 21.07.2016 / 23:24

1 answer

4

First, let's understand what || = means in your code. Basically, and for ease of understanding, you can translate the code into something more didactic like:

def adiciona(livro)
    @livros[livro.categoria] = @livros[livro.categoria] || []
    @livros[livro.categoria] << livro
end

To stay STILL clearer, this code could be translated into something like this too:

def adiciona(livro)
    @livros[livro.categoria] = [] unless @livros[livro.categoria]
    @livros[livro.categoria] << livro
end

In other words, if @books is nil (so it will be evaluated as false ), then an empty array will be assigned to the variable. Otherwise, the variable will retain the value it already has. But your code will be cleaner and clearer if you only use || = , do you agree? :)

Now talking about your problem. The point is that you are assigning an empty Array to the variable @books and then you are trying to treat it as a hash. Simply change your builder's code to:

def initialize
    @livros = {}
end
    
22.07.2016 / 16:25