Help with each_with_index method

C

Chris Pelow

Hi there,
I'm looking for help with my work here.I'm just learning Ruby.
Basically I have 5 names entered into an array. They have a firstname
and surname. A middlename is then optional.
What I want to do is to print out the names like this..
John Seymour Smith
Peter Jones
Mary Walsh

So it yields the middlename and prints it out if it has one.

Some of my code is as follows...

Code:
people << Person.new("John", "Paul", "Smith" )
people << Person.new("Mary","Barry", "Jones" )
people << Person.new("Chris","Townsend", "Barry" )
people << Person.new("Peter","", "Murphy" )
people << Person.new("Scott","", "Evans" )

people_sorted = people.sort
people_sorted.each do |person|
people_sorted.each_with_index do|person, index|
puts "Hi there #@index #@person!"
end

Attachments:
http://www.ruby-forum.com/attachment/4289/Person2.rb
 
J

Jeremy Woertink

Chris said:
Hi there,
I'm looking for help with my work here.I'm just learning Ruby.
Basically I have 5 names entered into an array. They have a firstname
and surname. A middlename is then optional.
What I want to do is to print out the names like this..
John Seymour Smith
Peter Jones
Mary Walsh

So it yields the middlename and prints it out if it has one.

Some of my code is as follows...

Code:
people << Person.new("John", "Paul", "Smith" )
people << Person.new("Mary","Barry", "Jones" )
people << Person.new("Chris","Townsend", "Barry" )
people << Person.new("Peter","", "Murphy" )
people << Person.new("Scott","", "Evans" )

people_sorted = people.sort
people_sorted.each do |person|
people_sorted.each_with_index do|person, index|
puts "Hi there #@index #@person!"
end


I was a bit confused by your post, but if I understand correctly, you
only want people with a middle name, and then print their names out?

ok, well to start, I would recommend including the curly braces when
you're using string interpolation. This way you can include your local
variables and not just instance variables.


people = []
people << Person.new({:firstname => "Billy", :middlename => "Jones",
:surname => "Smith"})
people << Person.new({:firstname => "Sally", :middlename => "", :surname
=> "Johnson"})

people.each do |person|
puts "Hello #{person.firstname}" unless person.middlename.empty?
end



Hope that helps.

~Jeremy Woertink
 
L

Lyle Johnson

Basically I have 5 names entered into an array. They have a firstname
and surname. A middlename is then optional.
What I want to do is to print out the names like this..
John Seymour Smith
Peter =A0 =A0 =A0 =A0Jones
Mary =A0 =A0 =A0 =A0 Walsh

So it yields the middlename and prints it out if it has one.

For starters, your Person class doesn't need to mix-in Enumerable, and
it doesn't need an "each" method. The array (people) that you're
adding Person instances to is the thing that is enumerable, and it has
its own each method built-in. So a trimmed down Person class could
look like so:

class Person
include Comparable
attr_accessor :firstname, :middlename, :surname

def initialize (firstname, middlename, surname)
@firstname =3D firstname
@middlename =3D middlename
@surname =3D surname
end

def to_s
"Hello my name is #@firstname #@surname and i'm #@age"
end

def <=3D> (other)
(self.firstname) <=3D> (other.firstname)
end
end

Your comparison method (the <=3D> method) isn't quite right, since it's
only comparing their first names, but I'll let you ponder how you
might improve that. You're on the right track.

Now, given your requirement for how you'd like the names to be
printed, I think I'd also add a full_name() method to the Person
class, something like:

class Person
def full_name
unless middlename.empty?
"#{firstname} #{middlename} #{surname}"
else
"#{firstname} #{surname}"
end
end
end

Finally, there are several issues with the bit at the end where you're
trying to iterate over the array of people. You have two loops (an
#each loop and then an #each_with_index loop) nested inside each
other. For the inner loop, the "index" and "person" arguments that
each_with_index() passes into the block aren't instance variables, so
you just refer to them as "index" and "person", not "@index" and
"@person". I'd change that last bit to look like this:

people_sorted =3D people.sort
people_sorted.each_with_index do |person, index|
puts "Hi there #{index} #{person.full_name}!"
end

Hope this helps,

Lyle
 
C

Chris Pelow

Now, given your requirement for how you'd like the names to be
printed, I think I'd also add a full_name() method to the Person
class, something like:

class Person
def full_name
unless middlename.empty?
"#{firstname} #{middlename} #{surname}"
else
"#{firstname} #{surname}"
end
end
end

Finally, there are several issues with the bit at the end where you're
trying to iterate over the array of people. You have two loops (an
#each loop and then an #each_with_index loop) nested inside each
other. For the inner loop, the "index" and "person" arguments that
each_with_index() passes into the block aren't instance variables, so
you just refer to them as "index" and "person", not "@index" and
"@person". I'd change that last bit to look like this:

people_sorted = people.sort
people_sorted.each_with_index do |person, index|
puts "Hi there #{index} #{person.full_name}!"
end

Hope this helps,

Lyle

Hi Lyle,

Thank you very much for your time in helping me here and for your
suggestions. You have also helped me understand it alot more so thank
you for that. I have made the suggested changes exactly how you
suggested however I am getting syntax errors for that full_name method
you gave me. Have I done it right?

Thanks alot,
Chris.

Attachments:
http://www.ruby-forum.com/attachment/4290/Person2.rb
 
R

Rob Biedenharn

Hi Lyle,

Thank you very much for your time in helping me here and for your
suggestions. You have also helped me understand it alot more so thank
you for that. I have made the suggested changes exactly how you
suggested however I am getting syntax errors for that full_name method
you gave me. Have I done it right?

Thanks alot,
Chris.

Attachments:
http://www.ruby-forum.com/attachment/4290/Person2.rb

Look very closely at the line having the error and match up all the
paired delimiters.

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
C

Chris Pelow

Chris said:
Still getting this error at runtime however



s/Person2.rb:22:in `full_name': undefined method `empty?' for
nil:NilClass (NoMethodError)
tware Patterns/Person2.rb:41
tware Patterns/Person2.rb:43:in `each_with_index'
tware Patterns/Person2.rb:40:in `each'
tware Patterns/Person2.rb:40:in `each_with_index'
tware Patterns/Person2.rb:40

Never mind I got it working.
Thanks a million for your help guys!
:)
 
R

Robert Klemme

2009/11/25 Chris Pelow said:
Never mind I got it working.
Thanks a million for your help guys!

Still a few more remarks: Method #to_s should return something usable
in the general case. In your example, to_s would probably better only
concatenate all three names. Including "Hello" and like stuff feels
wrong because it is unlikely that you always want to print that text
when showing Persons.

Then, for an absent name nil is a better value than the empty string.
That's exactly what nil stands for, nothing. That also makes
determining whether the person has a middle name easy.

And a last hint, you can use Struct very effectively to create
complete classes. This can greatly reduce the number of lines you
need for this class. You can find more here:
http://blog.rubybestpractices.com/posts/rklemme/017-Struct.html

Kind regards

robert
 
C

Chris Pelow

Robert said:
Still a few more remarks: Method #to_s should return something usable
in the general case. In your example, to_s would probably better only
concatenate all three names. Including "Hello" and like stuff feels
wrong because it is unlikely that you always want to print that text
when showing Persons.

Then, for an absent name nil is a better value than the empty string.
That's exactly what nil stands for, nothing. That also makes
determining whether the person has a middle name easy.

And a last hint, you can use Struct very effectively to create
complete classes. This can greatly reduce the number of lines you
need for this class. You can find more here:
http://blog.rubybestpractices.com/posts/rklemme/017-Struct.html

Kind regards

robert

Thanks alot Robert you've been a great help to me. This is the first
time i've used this forum and i've found it very helpful so thank you to
all that have helped me so far.
Chris.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top