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 Ruby Objects and Classes Build a Bank Account Class Part 4: Printing the register

Undefined method each ....

So I wrote a modified version of this project, just to see if I could get it to work. Everything works except: when I create an account and populate it with a few transactions, then try to print the register tape, I get this error:

tst.rb:60:in <main>': undefined methodeach' for nil:NilClass (NoMethodError)

I denoted line 60 with a comment.

can anyone help me figure out what I screwed up and how to not create this bug in the future?

This is the code I wrote:

class BankAccount
    attr_reader :name

    def initialize(name)
        @name = name
        @transactions = [] # I can't see anything here that should create a problem
    end

    def add_transaction(description, amount)
        @transactions.push(description: description, amount: amount)
    end

    def debit(description, amount)
        add_transaction(description, -amount)
    end

    def credit(description, amount)
        add_transaction(description, amount)
    end 

    def balance
        balance = 0.0
        @transactions.each do |transaction|
            balance += transaction[:amount]
        end 
        return balance
    end
end
one = 1

while one !=2

    puts("What do you want to do? 1. Open an account? 2. Debit an account? 3. Credit an account? 4. See an account history?")
    action = gets.chomp
        if action == '1' 
            puts("what is the name on the account?")
            nombre = gets
            puts("How much was the opening deposit?") 
            openingDeposit = Float(gets)
            createdAccount = BankAccount.new(nombre)
            createdAccount.credit("Opening Deposit", openingDeposit)
            puts("An account for #{createdAccount.name.chomp} was created with starting balance of #{createdAccount.balance}.")
        elsif action == '2'
            puts("Please provide a description of the transaction.")
            thisDescription = gets.chomp
            puts("Please enter an amount for the transaction")
            thisAmount = Float(gets)
            createdAccount.debit(thisDescription, thisAmount)
            puts("#{createdAccount.name.chomp}'s account has a current balance of #{createdAccount.balance}")
        elsif action == '3'
            puts("Please provide a description of the transaction.")
            thisDescription = gets.chomp
            puts("Please enter an amount for the transaction")
            thisAmount = Float(gets)
            createdAccount.credit(thisDescription, thisAmount)
            puts("#{createdAccount.name.chomp}'s account has a current balance of #{createdAccount.balance}")
        elsif action == '4'      #check this code block
            puts("Description: ".ljust(20) + "Balance ".rjust(10))

            @transactions.each do |transaction|        #    here is where the error is identified #by ruby
                puts(transaction[:description] + transaction[:amount])
            end
        else 
            puts("This is not a valid option. Please try again :)")
        end
        puts("Do you want to quit? Enter '2' to quit")
        one = Integer(gets)
end

4 Answers

Marco van Vemden
Marco van Vemden
12,553 Points

Hi David, on line 60, you need to access the transactions array through the instance of the BankAccount object. Line 61 also needs some adjustments. Here is the code for your transactions loop:

            createdAccount.transactions.each do |transaction|        #    here is where the error is identified #by ruby
                puts "#{transaction[:description]} #{transaction[:amount]}"
            end

Marco, thank you. How did I not see that?!

Marco van Vemden
Marco van Vemden
12,553 Points

Sorry David, my bad. Forgot to mention you have to add :transactions to the attr_reader, so on line 2:

attr_reader :name, :transactions

and remove the @ from @transactions on line 60, so

createdAccount.transactions.each do |transaction|

after these adjustments you will get an error on line 61, because a Float (the transaction amount) has no rjust() method. So you will need to change that.

I made the change, but I am still getting the same kind of error.

/home/ubuntu/workspace/bankaccounttest.rb:60:in <main>': undefined methodtransactions' for #<BankAccount:0x00000001cfd590> (NoMethodError)

(I am running this from a cloud workspace now)

If i use createdAccount.transactions the error above will be rendered when I run the program, create an account, enter a few transactions, and then select option 4: view account history. If i use createdAccount.@transactions to see if that worked, it will give the same error. I just figured I would try it and see if it worked.

This is the code now:

class BankAccount attr_reader :name

def initialize(name)
    @name = name
    @transactions = []
end

def add_transaction(description, amount)
    @transactions.push(description: description, amount: amount)
end

def debit(description, amount)
    add_transaction(description, -amount)
end

def credit(description, amount)
    add_transaction(description, amount)
end 

def balance
    balance = 0.0
    @transactions.each do |transaction|
        balance += transaction[:amount]
    end 
    return balance
end

end one = 1

while one !='2'

puts("What do you want to do? 1. Open an account? 2. Debit an account? 3. Credit an account? 4. See an account history?")
action = gets.chomp
    if action == '1' 
        puts("what is the name on the account?")
        nombre = gets
        puts("How much was the opening deposit?") 
        openingDeposit = Float(gets)
        createdAccount = BankAccount.new(nombre)
        createdAccount.credit("Opening Deposit", openingDeposit)
        puts("An account for #{createdAccount.name.chomp} was created with starting balance of #{createdAccount.balance}.")
    elsif action == '2'
        puts("Please provide a description of the transaction.")
        thisDescription = gets.chomp
        puts("Please enter an amount for the transaction")
        thisAmount = Float(gets)
        createdAccount.debit(thisDescription, thisAmount)
        puts("#{createdAccount.name.chomp}'s account has a current balance of #{createdAccount.balance}")
    elsif action == '3'
        puts("Please provide a description of the transaction.")
        thisDescription = gets.chomp
        puts("Please enter an amount for the transaction")
        thisAmount = Float(gets)
        createdAccount.credit(thisDescription, thisAmount)
        puts("#{createdAccount.name.chomp}'s account has a current balance of #{createdAccount.balance}")
    elsif action == '4'      #check this code block
        puts("Description: ".ljust(20) + "Balance ".rjust(10))

        createdAccount.@transactions.each do |transaction|
            puts("#{transaction[:description].ljust(20)}       #{transaction[:amount].rjust(10)}")
        end
    else 
        puts("This is not a valid option. Please try again :)")
    end
    puts("Do you want to quit? Enter '2' to quit")
    one = gets.chomp

end

Thanks, I got this thing working now! Only truly vital thing missing: some validations on the user inputs, and an ability to create and access multiple accounts.... That I can make later, that and make the code cleaner - making the things going on in the if .. else... to be individual functions/objects, not just a bunch of 'loose leaf' code.