What is the error in this program

class Customer
@@no_of_customers=0

def initialize(id, name, addr)
@id=id
@name=name
@addr=addr
end

def display_details()
puts “Customer ID #@id
puts “Customer Name #@name
puts “Customer Address #@addr
@@no_of_customers+=1
end

def total_customers
puts “total no. of customers are #@@no_of_customers
end
end

while($_!=“n”)
index=0;
print "Enter user id "
id=gets
chomp
print "Enter user name "
name=gets
chomp
print "Enter user address "
addr=gets
chomp
cust=Array.new
cust[index]=Customer.new(id,name,addr)
index+=1
print "do you want to enter more data y/n "
gets
chomp
end

0.upto(index-1) do |c|
puts cust[c].display_details()
end

Whenever i run this program and provide the input the display_details
function show the details of only the last customer.

Manish Kutaula wrote:

while($_!=“n”)
 index=0;
 […]
 index+=1
 […]
 end

You set index to 0 at every iteration of the loop.

HTH,
Sebastian

On Sat, Jun 14, 2008 at 2:53 PM, Sebastian H. <
[email protected]> wrote:

You set index to 0 at every iteration of the loop.

Yes, but beyond that here’s a critique of this code in the way of a
refactoring:

class Customer
@@no_of_customers=0 # I personally wouldn’t use a class variable
here,
but I’ll let it go.

def initialize(id, name, addr)
@id=id
@name=name
@addr=addr
# If we are really counting customers we should do it
# when they each customer is created
# not when they are displayed since
# a customer just might get displayed more than once
# or not at all.
@@no_of_customers+=1
end

def display_details()
puts “Customer ID #@id
puts “Customer Name #@name
puts “Customer Address #@addr
end

I’d make this a class method since the number of customers

is a property of the class rather than each instance.

def self.total_customers
puts “total no. of customers are #@@no_of_customers
end
end

This was just too C/Fortran like, let’s treat the array like

an object, not just a static array!

Since we’re collecting the customers here,

we need to instantiate the array once, not everytime

through the loop, and let’s use a clearer name:

customers = []

Let’s lose the magic variable $_! and make this a

bit more understandable

more = “y”

note also that this was $_! = “n” which is an assignment

NOT a comparison

until(more == “n”)
print "Enter user id "

We need to send chomp to the string we got, not self!

id=gets chomp
print "Enter user name "
name=gets chomp
print "Enter user address "
addr=gets chomp

Let the array keep track of how many elements it has

customers << Customer.new(id,name,addr)
print "do you want to enter more data y/n "
more = gets chomp
end

And using each is much less bug prone than a C/Basic/Fortran-like

loop:
customers.each do |customer|
puts customer.display_details()
end

I note that this code doesn’t actually use the total_customers method,
with
the change I made this would be done with

puts Customer.total_customers

However if the real requirement is to get the number of Customers we
processed in the loop, then we can
do away with the counter and the class method and just use

puts customers.length


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/