Ruby Build an Address Book in Ruby Search Searching By Address

Nafeez Quraishi
Nafeez Quraishi
7,093 Points

why ruby asks me to type additional "end" (s) apart from the ones needed for closing loop, function and class.

why ruby asks me to type additional "end" (s) apart from the ones needed for closing loop, function and class.

if i do not do this, i get "syntax error, unexpected end-of-input, expecting keyword_end"

for example in the code below i had to add two ends at last:

require "./Contact"

class AddressBook
  attr_accessor :ab_contacts

  $ab_contacts = []

  def intitialize
#    @ab_contacts = Array.new()
  end

  def find_by_name(name)
    puts "-------finding by name -------"
    results = []
    search = name.downcase
    #puts $ab_contacts.class
     $ab_contacts.each do |c|
      if c.first_name.downcase.include?(name)
        results.push(c)
      end
     end

     results.each do |c|
       puts c.to_s('full_name')
       c.print_phone_numbers
       c.print_address
       puts "\n"
     end

  end

  def find_by_phone_number(number)
    puts "-------finding by phone number-----" 
    results = []
    search = number.gsub("-","")
    $ab_contacts.each do |c|
      c.phone_numbers.each do |n|
          if n.number.gsub("-","").include?(search)
            results.push(c) unless results.include?(c)
          end
    end
    results.each do |c|
      puts c.to_s('full_name')
      c.print_phone_numbers
      c.print_address
      puts "\n"
   end
  end

  def find_by_address(add)
    puts "-----------finding by address------------"
    results = []
    search = query.downcase
    $ab_contacts.each do |c|
      c.addresses.each do |a|
        if a.to_s('long').downcase.include?(search)
          results.push(c) unless results.include?(c)
        end
      end
    end
    results.each do |c|
      puts c.to_s('full_name')
      c.print_phone_numbers
      c.print_address
      puts "\n"

  end

  def print_contact_list
    $ab_contacts.each do |c|
      puts c.to_s('last_first')
    end
  end

end



me = Contact.new
me.first_name = "AAA"
me.middle_name = "BBB"
me.last_name = "CCC"

me.add_phone_number('first_no', '111111111')
me.add_phone_number('second_no', '2222222222')

me.add_address('Home', "my house", 'my street one', 'my city', "my state", "999999")
me.add_address('Office', 'my office', 'my office street', 'my city', "my state", '9999111')


my_frnd = Contact.new
my_frnd.first_name = "DDD"
my_frnd.middle_name = "EEE"
my_frnd.last_name = "FFF"

my_frnd.add_address('Home', "frnd house", 'frnd street one', 'frnd city', "frnd state", "999999")
my_frnd.add_address('Office', 'frnd office', 'frnd office street', 'frnd city', "frnd state", '9999111')
my_frnd.add_phone_number('first_no', '999999999')
my_frnd.add_phone_number('second_no', '555555555')



address_book = AddressBook.new
#puts address_book.ab_contacts.class.to_s()
$ab_contacts.push(me)
$ab_contacts.push(my_frnd)
#address_book.print_contact_list

address_book.find_by_name("d")
address_book.find_by_phone_number("555")
address_book.find_by_address("frnd")
  end 
end

2 Answers

Jay McGavren
STAFF
Jay McGavren
Treehouse Teacher

This is a very large code sample, and if you are missing an end keyword anywhere, you will get a syntax error. Adding "end" keywords at the end might fix the syntax errors, but it will also place all of the code inside whatever class or method was missing an end keyword, which will lead to other bugs. It's important to find the correct place to put the missing end.

Fortunately, because you were careful with your indentation, I was able to immediately spot the two places you were missing end keywords. My updates to your code are below, with comments.

I learned a great habit, I think it may have been from Jeff Atwood's blog, that I've been using for over 10 years now. Anytime I type an opening delimiter ((, {, [, def, do, etc.), I immediately type the closing delimiter (), }, ], end, etc.) after it. Only then do I use the arrow keys to go back and type whatever I need between the two delimiters. You can see me doing this here in this video Because of this habit, I never have problems with missing closing delimiters. Every developer should consider following this habit too, it will save you a lot of trouble!

require "./Contact"

class AddressBook
  attr_accessor :ab_contacts

  $ab_contacts = []

  def intitialize
#    @ab_contacts = Array.new()
  end

  def find_by_name(name)
    puts "-------finding by name -------"
    results = []
    search = name.downcase
    #puts $ab_contacts.class
     $ab_contacts.each do |c|
      if c.first_name.downcase.include?(name)
        results.push(c)
      end
     end

     results.each do |c|
       puts c.to_s('full_name')
       c.print_phone_numbers
       c.print_address
       puts "\n"
     end

  end

  def find_by_phone_number(number)
    puts "-------finding by phone number-----" 
    results = []
    search = number.gsub("-","")
    $ab_contacts.each do |c|
      c.phone_numbers.each do |n|
          if n.number.gsub("-","").include?(search)
            results.push(c) unless results.include?(c)
          end
      # Added "end" here.
      end
    end
    results.each do |c|
      puts c.to_s('full_name')
      c.print_phone_numbers
      c.print_address
      puts "\n"
   end
  end

  def find_by_address(add)
    puts "-----------finding by address------------"
    results = []
    search = query.downcase
    $ab_contacts.each do |c|
      c.addresses.each do |a|
        if a.to_s('long').downcase.include?(search)
          results.push(c) unless results.include?(c)
        end
      end
    end
    results.each do |c|
      puts c.to_s('full_name')
      c.print_phone_numbers
      c.print_address
      puts "\n"
    # Added "end" here.
    end
  end

  def print_contact_list
    $ab_contacts.each do |c|
      puts c.to_s('last_first')
    end
  end

end



me = Contact.new
me.first_name = "AAA"
me.middle_name = "BBB"
me.last_name = "CCC"

me.add_phone_number('first_no', '111111111')
me.add_phone_number('second_no', '2222222222')

me.add_address('Home', "my house", 'my street one', 'my city', "my state", "999999")
me.add_address('Office', 'my office', 'my office street', 'my city', "my state", '9999111')


my_frnd = Contact.new
my_frnd.first_name = "DDD"
my_frnd.middle_name = "EEE"
my_frnd.last_name = "FFF"

my_frnd.add_address('Home', "frnd house", 'frnd street one', 'frnd city', "frnd state", "999999")
my_frnd.add_address('Office', 'frnd office', 'frnd office street', 'frnd city', "frnd state", '9999111')
my_frnd.add_phone_number('first_no', '999999999')
my_frnd.add_phone_number('second_no', '555555555')



address_book = AddressBook.new
#puts address_book.ab_contacts.class.to_s()
$ab_contacts.push(me)
$ab_contacts.push(my_frnd)
#address_book.print_contact_list

address_book.find_by_name("d")
address_book.find_by_phone_number("555")
address_book.find_by_address("frnd")
# All of the above code was PART of the AddressBook class!
# We don't want that. Now that the "end" keywords are in the correct place, it should be OK.
# "end" keywords here are no longer necessary
#  end 
# end
Nafeez Quraishi
Nafeez Quraishi
7,093 Points

Ohh my bad! i did not look at closely enough and thought too soon that its some non-syntax issue. Thanks a lot for reverting with a detailed reply and pointing damages seemingly syntax problem fixing end keywords at the End can cause. Also, thanks a lot for sharing the tip!!