Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Ruby

Saad Khan Malik
Saad Khan Malik
25,199 Points

[Solved] `add_contact': undefined method `push'

I have the exact code from the project, the only thing different is that I'm developing locally

this the error my console spits out

address_book.rb:96:in `add_contact': undefined method `push' for false:FalseClass (NoMethodError)
        from address_book.rb:35:in `block in run'
        from address_book.rb:25:in `loop'
        from address_book.rb:25:in `run'
        from address_book.rb:155:in `<main>'

and my (copied) code...

require "./contact"
require "yaml"

class AddressBook
    attr_reader :contacts

    def initialize
        @contacts = []
        open()
    end

    def open
        if File.exist?("contacts.yml")
            @contacts = YAML.load_file("contacts.yml")
        end
    end

    def save
        File.open("contacts.yml", "w") do |file|
            file.write(contacts.to_yaml)
        end
    end

    def run
        loop do
            puts "Address Book"
            puts "a: Add Contact"
            puts "p: Print Address Book"
            puts "s: Search"
            puts "e: Exit"
            print "Enter your choice: "
            input = gets.chomp.downcase
            case input
            when 'a'
                add_contact
            when 'p'
                print_contact_list
            when 's'
                print "Search term: "
                search = gets.chomp
                find_by_name(search)
                find_by_phone_number(search)
                find_by_address(search)
            when 'e'
                save()
                break  
            end
            puts "\n"
        end
    end

    def add_contact
        contact = Contact.new
        print "First name: "
        contact.first_name = gets.chomp
        print "Middle name: "
        contact.middle_name = gets.chomp
        print "Last name: "
        contact.last_name = gets.chomp

        loop do
            puts "Add phone number or address? "
            puts "p: Add phone number"
            puts "a: Add address"
            puts "(Any other key to go back)"
            response = gets.chomp.downcase
            case response
            when 'p'
                phone = PhoneNumber.new
                print "Phone number kind (Home, Work, etc): "
                phone.kind = gets.chomp
                print "Number: "
                phone.number = gets.chomp
                contact.phone_numbers.push(phone)
            when 'a'
                address = Address.new
                print "Address Kind (Home, Work, etc): "
                address.kind = gets.chomp
                print "Address line 1: "
                address.street_1 = gets.chomp
                print "Address line 2: "
                address.street_2 = gets.chomp
                print "City: "
                address.city = gets.chomp
                print "State: "
                address.state = gets.chomp
                print "Postal Code: "
                address.postal_code = gets.chomp
                contact.addresses.push(address)
            else
                print "\n"
                break
            end
        end

        contacts.push(contact)
    end

    def print_results(search, results)
        puts search
        results.each do |contact|
            puts contact.to_s('full_name')
            contact.print_phone_numbers
            contact.print_addresses
            puts "\n"
        end
    end

    def find_by_name(name)
        results = []
        search = name.downcase
        contacts.each do |contact|
            if contact.full_name.downcase.include?(search)
                results.push(contact)
            end
        end
        print_results("Name search results (#{search})", results)
    end

    def find_by_phone_number(number)
        results = []
        search = number.gsub("-", "")
        contacts.each do |contact|
            contact.phone_numbers.each do |phone_number|
                if phone_number.number.gsub("-", "").include?(search)
                    results.push(contact) unless results.include?(contact)
                end
            end
        end
        print_results("Phone search results (#{search})", results)
    end

    def find_by_address(query)
        results = []
        search = query.downcase
        contacts.each do |contact|
            contact.addresses.each do |address|
                if address.to_s('long').downcase.include?(search)
                    results.push(contact) unless results.include?(contact)
                end
            end
        end
        print_results("Address search results (#{search})", results)
    end

    def print_contact_list
        puts "Contact List"
        contacts.each do |contact|
            puts contact.to_s('last_first')
        end
    end
end

address_book = AddressBook.new
address_book.run

any ideas why this is happening... Thanks!

1 Answer

Gavin Ralston
Gavin Ralston
28,770 Points
address_book.rb:96:in `add_contact': undefined method `push' for false:FalseClass

That error message points to line 96 in the address_book class.

It's telling you that you're trying to call the push method on False, and not on the object you intended.

It looks like you wanted to push to @contacts -- double check to see if you're using the correct variable in your loop in order to get to the object you want.

Like, for instance, what happens if it can't load the contact file earlier on in your open method?

def open
        if File.exist?("contacts.yml")
            @contacts = YAML.load_file("contacts.yml")
        end
    end

Would the result of a failed load make @contacts point to false instead of the list of contacts like you were expecting?

Saad Khan Malik
Saad Khan Malik
25,199 Points

Thanks I was able to identify that the open method was producing the error. I removed the ' @ ' from

@contacts = YAML.load_file("contacts.yml")

and everything was working fine....

after a few entries and saves the contacts.yml file deleted all its entries

after which i put the ' @ ' symbol back ... and now everything is working silky smooth...

its sooo strange...