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 trialDavid Thrower
6,693 PointsUndefined 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 method
each' 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
12,553 PointsHi 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 van Vemden
12,553 PointsSorry 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.
David Thrower
6,693 PointsI made the change, but I am still getting the same kind of error.
/home/ubuntu/workspace/bankaccounttest.rb:60:in <main>': undefined method
transactions' 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
David Thrower
6,693 PointsThanks, 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.
David Thrower
6,693 PointsDavid Thrower
6,693 PointsMarco, thank you. How did I not see that?!