1

I have a YAML file books.yaml:

 - !ruby.object:Book
  title: Ruby for Newbz
  author: LeeRoy Jenkins
  category: Educational

I already have a method that adds books to this file, but I need a method that can search the YAML file using a regular expression. If no book matches the title then it should raise an exception NoBookfound. If there are any matches, that list should be returned to the caller.

Here is my existing code:

require 'yaml'
require './book'
class Library
  attr_accessor :books

  def initialize file_name = false
    @books = file_name ? YAML::load(File.read(file_name)) : []

  end

  def add_book(book)
    @books.push(book) 

  end

  def search_library(file_name , book) 
    if
      YAML::load(File.read(file_name)).include?(book) == false
      raise 'No Book Found'
    end
  end

end

This is something I tried for the exception portion, but I feel like I'm way off. I'm really new to Ruby and this seems to be a pretty hard task. Does anyone have any ideas?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303

3 Answers3

0

What you need is to test the class from the loaded object:

book = YAML::load(File.read(file_name))
raise 'No Book Found' unless book.kind_of? Book

There are also some kind_of? alternatives, which you can read about the differences on this nice question

Community
  • 1
  • 1
fotanus
  • 19,618
  • 13
  • 77
  • 111
0

Based on your post, I guess that book param is a Regexp object. I think you should remove the file_name param from search method, since the file is already loaded on initialize method.

My implemetation would be:

def search_library term
  @books.find_all {|b| b.title =~ term}
end
Thiago Lewin
  • 2,810
  • 14
  • 18
  • Actually, `file_name` refers to the YAML file and there is a seperate Book class that just initializes the three descriptors `@title` `@author` and `@category` – Hubert Wolski Jun 03 '13 at 19:42
  • Yes, I got it, but I think it is a little bit confusing if you load the file two times. No to mention that you will lose all objects from add_book method. If you want to keep the file_name, I think that would be better if you make this method static: def self.search_library(file_name, term) ... – Thiago Lewin Jun 04 '13 at 00:04
  • I see what you're saying, my instructor pointed this out as well. Thanks for the help! – Hubert Wolski Jun 04 '13 at 15:17
0

Since you already have "@books" in an enumerable you can use the select method to find books whose title have the search term as a substring.

def search_library(term)
  matches = @books.select { |x| x.title.index(term) }
  raise "No books have title like '#{term}'" if matches.empty?
  matches
end
maerics
  • 151,642
  • 46
  • 269
  • 291