Stepping out on a Limb - some very ugly code


#1

Hi all,

I’ve spent a few minutes this morning working on some code for that
Resume
Builder that was suggested to me on this list a few weeks ago…

I have written some horribly ugly procedural code and wanted to get some
input as to how I can make it more Ruby like.

My code is exceedingly redundant. The only “woohoo!” I have about it,
is
that I didn’t have to look anything up in reference to write it.

Anyway, I’m stepping out on a limb here and putting out some stuff…
I’ve
ran the code and it works and does what I want… I just know that it’s
horribly tedious.

:slight_smile:

Thanks!

(PS - Don’t make fun of me too harshly :slight_smile: )

#ResumeBuilder.rb

puts(“Welcome to ResumeBuilder v.1”)
puts("Please enter your first name: ")
first_name = gets.chomp.capitalize!
puts("Please enter your last name: ")
last_name = gets.chomp.capitalize!
full_name = first_name + " " + last_name
puts(“You have entered " + full_name + " as your name. Is this correct?
(yes/no)”)
correct = gets.chomp
if correct.downcase == “yes”: puts("Excellent, " + first_name + “!”)
else puts("Please enter your first name: ")
first_name = gets.chomp.capitalize!
puts("Please enter your last name: ")
last_name = gets.chomp.capitalize!
puts("You have entered " + full_name + “! Is this correct?
(yes/no)”)
correct = gets.chomp
if correct.downcase == “yes”: puts("Great, let’s get started, " +
first_name + “!”)
else puts(“Please come back when you know your name.”)
end
end

puts("Please enter your street number: ")
street_number = gets.chomp!
puts("Please enter your street name: ")
street_name = gets.chomp.capitalize!
puts("Please enter your city name: ")
city_name = gets.chomp.capitalize!
puts("Please enter your state: ")
state_name = gets.chomp.upcase!
puts(“Please enter your zip code: “)
zip_code = gets.chomp!
puts(“You have told me that you live at:\n” + street_number + " " +
street_name +”\n” + city_name + ", " + state_name + " " + zip_code +
“\nIs
this correct? (yes/no)”)
correct = gets.chomp
if correct.downcase == “yes”: puts(“Great, let’s continue!”)
else puts("Please enter your street number: ")
street_number = gets.chomp!
puts("Please enter your street name: ")
street_name = gets.chomp.capitalize!
puts("Please enter your city name: ")
city_name = gets.chomp.capitalize!
puts("Please enter your state: ")
state_name = gets.chomp.upcase!
puts(“Please enter your zip code: “)
zip_code = gets.chomp!
puts(“You have told me that you live at:\n” + street_number + " " +
street_name +”\n” + city_name + ", " + state_name + " " + zip_code +
“\nIs
this correct? (yes/no)”)
if correct.downcase == “yes”: puts(“Great, let’s continue!”)
else puts(“Please come back when you know where you live.”)
end
end


Samantha

http://www.babygeek.org/

“Beware when the great God lets loose a thinker on this planet. Then all
things are at risk.”
–Ralph Waldo Emerson


#2

On Thu, 1 Mar 2007 02:56:25 +0900, Samantha removed_email_address@domain.invalid
wrote:

I have written some horribly ugly procedural code and wanted to get some
input as to how I can make it more Ruby like.

Hi, thanks for writing. It sounds like you have a fairly good sense of
code aesthetics already, which will help you out as you progress. Just
don’t be too hard on yourself; while you correctly recognize that
there’s room for improvement, your code isn’t too bad, given what it
does.

That said, I guess three things stand out at the moment – two are a
matter of Ruby style, the other isn’t really Ruby-specific.

First, it’s probably more readable to avoid the “if cond:” syntax,
particularly with an else clause. For instance, try this:

if correct.downcase == “yes”
puts(“Great, let’s continue!”)
else
puts(“Please come back when you know where you live.”)
end

instead of this:

if correct.downcase == “yes”: puts(“Great, let’s continue!”)
else puts(“Please come back when you know where you live.”)
end

The second thing is that it’s often more readable to take advantage of
Ruby’s string interpolation. For instance, you can write this:

puts(“You have entered #{ full_name } as your name. Is this correct?
(yes/no)”)

instead of this:

puts(“You have entered " + full_name + " as your name. Is this
correct? (yes/no)”)

(admittedly, in this particular case, it’s almost purely a question of
taste – there’s not a huge readability advantage between the two; the
first is just more “idiomatic”)

The third thing is about looking for recurring patterns in the code; the
presence of such patterns has a lot to do with “ugly” code. The best
way to deal with them is to factor them out – in very much the same
sense that you could rewrite 3x + 2x^2 as x(3 + 2x).

For instance: the main recurring pattern is a puts, followed by a
gets.chomp. We can pull that out into a separate function:

def prompt(string)
puts(string)
gets.chomp
end

And rewrite the prompts accordingly:

puts(“Welcome to ResumeBuilder v.1”)
first_name = prompt("Please enter your first name: ").capitalize!
last_name = prompt("Please enter your last name: ").capitalize!
full_name = “#{ first_name } #{ last_name }”

(etc.)

At this point, another pattern becomes apparent: asking for a yes/no
answer and checking whether it is equal to “yes”. We can use the
“prompt” function we’ve already built as part of another one just for
yes/no answers:

def boolean_prompt(string)
prompt("#{ string } (yes/no)").downcase == “yes”
end

And then you can rewrite the yes/no questions like this:

correct = boolean_prompt(“You have entered #{ full_name } as your
name. Is this correct?”)
if correct
puts(“Great, let’s get started, #{ first_name }!”)
else
puts(“Please come back when you know your name.”)
exit 1
end

[ note that I’ve added an “exit 1” to leave the program in the case
where the name was wrong, which seems to have been your intent? ]

Anyway, those are the major items which come to mind at the moment. We
could probably continue refactoring the code like this a little bit
further (for instance, a “prompt” function just for capitalized input),
but I think that’d be passsing a point of diminishing returns – your
program is already a pretty concise expression of what it does. Also,
because of that, don’t worry too much that your program isn’t using
classes or other “special” Ruby features just yet – as you add more
functionality to your program, there will be plenty of opportunities to
refactor code to use them.

-mental


#3

Samantha wrote:

My code is exceedingly redundant. The only “woohoo!” I have about it, is
that I didn’t have to look anything up in reference to write it.
Well, I’m new to ruby too, but the most obvious things I would do is
loop the gets so that you don’t write everything twice, and make a
method to handle the gets so that you don’t write that 10 times. As far
as making it more “rubyish”, I’m sure I would mess that up, but I guess,
with that in mind, I would at least put it in a class, and I personally
like using string interpolation, it’s more readable for me.

Raj

#ResumeBuilder.rb

class ResumeBuilder
def initialize
puts(“Welcome to ResumeBuilder v.1”)
correct = “”
until correct.downcase == “yes”
@first_name = prompt_and_get(“first name”).chomp.capitalize
@last_name = prompt_and_get(“last name”).chomp.capitalize
@full_name = “#{@first_name} #{@last_name}”
puts(“You have entered #{@full_name} as your name.
Is this correct? (yes/no)”)
correct = gets.chomp
end
correct = “”
until correct.downcase == “yes”
@street_number = prompt_and_get(“street number”).chomp
@street_name = prompt_and_get(“street name”).chomp.capitalize
@city_name = prompt_and_get(“city name”).chomp.capitalize
@state_name = prompt_and_get(“state”).chomp.upcase
@zip_code = prompt_and_get(“zip code”).chomp
puts “You have told me that you live at:
#{@street_number} #{@street_name}
#{@city_name}, #{@state_name} #{@zip_code}
Is this correct? (yes/no)”
correct = gets.chomp
end
end

def prompt_and_get(string)
puts "Please enter your #{string}: "
gets
end
end

ResumeBuilder.new


#4

On 2/28/07, MenTaLguY removed_email_address@domain.invalid wrote:

end

instead of this:

if correct.downcase == “yes”: puts(“Great, let’s continue!”)
else puts(“Please come back when you know where you live.”)
end

That’s funny! :slight_smile: I Say that because I normally write my if/else
statements
like that, but decided to try it with the : syntax

The second thing is that it’s often more readable to take advantage of

(admittedly, in this particular case, it’s almost purely a question of
taste – there’s not a huge readability advantage between the two; the first
is just more “idiomatic”)

nod That makes sense, especially because I ended up running into
syntax
errors because it’s easy to miss putting in a + sign.

The third thing is about looking for recurring patterns in the code; the

presence of such patterns has a lot to do with “ugly” code. The best way to
deal with them is to factor them out – in very much the same sense that you
could rewrite 3x + 2x^2 as x(3 + 2x).

And, that’s exactly where I knew I could improve and where I was having
problems minimizing the code.

For instance: the main recurring pattern is a puts, followed by a
gets.chomp. We

can pull that out into a separate function:

def prompt(string)
puts(string)
gets.chomp
end

And rewrite the prompts accordingly:

Ohhhh. I like it.

puts(“Welcome to ResumeBuilder v.1”)

def boolean_prompt(string)
puts(“Please come back when you know your name.”)
exit 1
end

[ note that I’ve added an “exit 1” to leave the program in the case where
the name was wrong, which seems to have been your intent? ]

Yeah, that was my intent, I just wasn’t 100% sure how to get out of
there.
I gave the user two chances to properly input their answer, and if they
couldn’t get their name right they were SOL.

Anyway, those are the major items which come to mind at the moment. We

could probably continue refactoring the code like this a little bit further
(for instance, a “prompt” function just for capitalized input), but I think
that’d be passsing a point of diminishing returns – your program is already
a pretty concise expression of what it does. Also, because of that, don’t
worry too much that your program isn’t using classes or other “special” Ruby
features just yet – as you add more functionality to your program, there
will be plenty of opportunities to refactor code to use them.

Thanks! So I guess I did get something out of my Programming Logic &
Design
class last semester. I really appreciate your response. It shed light
on
what I wanted to do. :slight_smile:

-mental


Samantha

http://www.babygeek.org/

“Beware when the great God lets loose a thinker on this planet. Then all
things are at risk.”
–Ralph Waldo Emerson


#5

On 2/28/07, Raj S. removed_email_address@domain.invalid wrote:

Well, I’m new to ruby too, but the most obvious things I would do is

class ResumeBuilder
end
Is this correct? (yes/no)"
ResumeBuilder.new

Thanks for the answer, Raj. I think that this is going to be a good way
for
me to learn and improve!


Samantha

http://www.babygeek.org/

“Beware when the great God lets loose a thinker on this planet. Then all
things are at risk.”
–Ralph Waldo Emerson


#6

Am Mittwoch, 28. Februar 2007 18:56:25 schrieb Samantha:

puts("Please enter your street number: ")
street_number = gets.chomp!
puts("Please enter your street name: ")
street_name = gets.chomp.capitalize!
puts("Please enter your city name: ")
city_name = gets.chomp.capitalize!
puts("Please enter your state: ")
state_name = gets.chomp.upcase!
puts("Please enter your zip code: ")
zip_code = gets.chomp!

How about something like this instead?

data=Hash.new
[“street number”,“street name”,“city name”,“state”,“zip code”].each do
|i|
puts("Please enter your #{i}: ")
data[i]=gets.chomp
end

HTH,
Sebastian


#7

Samantha wrote:


Samantha

http://www.babygeek.org/

“Beware when the great God lets loose a thinker on this planet. Then all
things are at risk.”
–Ralph Waldo Emerson
thanx sammantha for asking…i’ve printed these suggestions and will
put into use myself…dave


#8

On 2/28/07, Sebastian H. removed_email_address@domain.invalid wrote:

puts("Please enter your zip code: ")
zip_code = gets.chomp!

How about something like this instead?

data=Hash.new
[“street number”,“street name”,“city name”,“state”,“zip code”].each do |i|
puts("Please enter your #{i}: ")
data[i]=gets.chomp
end

That’s an angle I hadn’t even thought of! Thank you!

HTH,

Sebastian

NP: Anathema - Suicide Veil
Ist so, weil ist so
Bleibt so, weil war so


Samantha

http://www.babygeek.org/

“Beware when the great God lets loose a thinker on this planet. Then all
things are at risk.”
–Ralph Waldo Emerson


#9

On 2/28/07, Samantha removed_email_address@domain.invalid wrote:

|i|
NP: Anathema - Suicide Veil
Ist so, weil ist so
Bleibt so, weil war so

Okay … I wrote that up and it inputs things, but I have a few
questions…

  1. After getting the information from the user, I want to be able to
    output
    the information on the screen and get a confirmation. I’m assuming that
    I
    do that with:

contact_info.each do |i|
puts i
end

Yes? So… 1) How do I get this to be ‘pretty’ or formatted nicely like
the
original code, and 2) How do I get the state abbreviation as all upcase?


Samantha

http://www.babygeek.org/

“Beware when the great God lets loose a thinker on this planet. Then all
things are at risk.”
–Ralph Waldo Emerson


#10

On 2/28/07, Sebastian H. removed_email_address@domain.invalid wrote:

data[i]=gets.chomp

name"] to access the street name), assuming contact_info is what you
called
the hash (although I would recommend just calling it info, because that’s
less
to type :wink: )

Gotcha, so… i’d type

puts contact_info[“state_name”].upcase

to access and change the state abbreviation to all uppercase, then,
yes? :slight_smile:

Thanks again for being so helpful!

Being that I wrote out the ‘procedural’ type code before, I am going to
use
all these tips and rewrite the same program piece and add on to it,
using
different techniques…

:slight_smile:

Ist so, weil ist so
Bleibt so, weil war so


Samantha

http://www.babygeek.org/

“Beware when the great God lets loose a thinker on this planet. Then all
things are at risk.”
–Ralph Waldo Emerson


#11

Am Mittwoch, 28. Februar 2007 20:52:44 schrieb Samantha:

On 2/28/07, Samantha removed_email_address@domain.invalid wrote:

On 2/28/07, Sebastian H. removed_email_address@domain.invalid wrote:

data=Hash.new
[“street number”,“street name”,“city name”,“state”,“zip code”].each do
|i|
puts("Please enter your #{i}: ")
data[i]=gets.chomp
end

Yes? So… 1) How do I get this to be ‘pretty’ or formatted nicely like
the original code, and 2) How do I get the state abbreviation as all
upcase?

Just use contact_info[“x”] to access information x (e.g.
contact_info[“street
name”] to access the street name), assuming contact_info is what you
called
the hash (although I would recommend just calling it info, because
that’s less
to type :wink: )


#12

After taking several suggestions, I’ve come up with 91 lines of code
(including blank lines because I like organizing things).

I have a few issues in certain areas of the code…

I’ll post all 91 lines (including lines intentionally left blank), and
explain what I’m having go wrong… I’m just not getting it, but maybe I
don’t quite understand certain things… (probably, not maybe :wink: (And
please excuse the rude prompts - I’m not really this rude, nor would I
write
such a rude program for deployment into the world.)

#ResumeBuilder.rb

#This is the section that defines a prompt.
def prompt(string)
puts(string)
gets.chomp
end

#This section defines a prompt that requires a yes or no answer.
def boolean_prompt(string)
prompt("#{string} (yes/no)").downcase == “yes”
end

#Main program logic for User Identity
puts(“Welcome to Resume Builder v.1”)

first_name = prompt("Please enter your first name: ").capitalize!
last_name = prompt("Please enter your last name: ").capitalize!

#This verifies that the user is who they said they were.
correct = boolean_prompt(“So, your name is #{first_name} #{last_name}?”)
if correct
puts(“Great! Let’s get started, #{first_name}!”)
else
puts(“Please come back when you know who you are.”)
exit 1
end

------------When I get to this point, if I typed in the answers to the
prompts with the first letter capitalized (ie Samantha for the first
name),
when the program verifies what I typed whatever values it is verifying,
as
blank…

#now we get the address information of the user
street_number = prompt("Please enter your street number: ")
street_name = prompt("Please enter your street name: ").capitalize!
city_name = prompt("Please enter your city name: ").capitalize!
state_name = prompt("Please enter the state you live in: ").upcase!
zip_code = prompt("Please enter your zip code: ")
phone_number = prompt("Please enter your phone number in the following
format: (999) 999-9999: ")
email_address = prompt("Please enter your email address in the follwoing
format: removed_email_address@domain.invalid: ")

correct = boolean_prompt("Your address is: \n#{street_number}
#{street_name}\n#{city_name}, #{state_name} #{zip_code}\nYour phone
number
is #{phone_number} and your email address is #{email_address}.\nIs this
correct? ")
if correct
puts(“Great! Let’s continue!”)
else
puts(“Please come back when you know where you live.”)
exit 1
end

#this section gets the objective of the candidate.
objective = prompt(“Please enter a short description of your career
objective, making sure you use proper rules of capitalization.”)
correct = boolean_prompt(“You said your career objective is,
“#{objective}” Is this correct?” )
if correct
puts(“Good, now moving on, let’s get a little information about your
skills.”)
else
puts(“Please come back when you have some goals.”)
exit 1
end

#this section gathers the skillset of the user and puts them into an
array.
puts(“Please enter your technical skills - one per line. When you are
complete, please leave a blank line and hit enter.”)
tech_skills = []
while (answer = gets.chomp)
break if answer.empty?
tech_skills.push(answer)
end

puts(“Your skills are as follows:\n”)
tech_skills.each do |skill|
puts skill
end

correct = boolean_prompt(“Is this correct?”)
if correct
puts(“Great, let’s move onto your experience.”)
else
puts(“Please come back when you know what you can do with yourself.
:)”)
exit 1
end

#This section gathers experience from the user.
company1 = Hash.new
[“Company Name”,“Company City”,“Company State”,“Start Date”,“End
Date”,“Position Held”,“Job Duties”].each do |input|
puts("Please enter your #{input}: ")
company1 = gets.chomp
end

correct = boolean_prompt(“You worked at " + company1[“Company Name”] + "
as
a " + company1[“Position Held”] + " from " + company1[“Start Date”] + "
until " + company1[“End Date”] + " and your job description was as
follows:
\n” + company1[“Job Duties”] + “\n” + company1[“Company Name”] + " was
located in " + company1[“Company City”] + ", " + company1[“Company
State”] +
"Is this correct? ")
if correct
puts(“Great, let’s move on!”)
else
puts(“Please come back when you have some experience to add to your
resume. In other words, GET A JOB! :)”)
exit 1
end

------------------The above section of code, from the hash section
down…
gives an error… This is the output…

Is this correct? (yes/no)
yes
Great, let’s move onto your experience.
Please enter your Company Name:
asdf
Please enter your Company City:
asdf
Please enter your Company State:
asdf
Please enter your Start Date:
April 2005
Please enter your End Date:
January 2007
Please enter your Position Held:
blah
Please enter your Job Duties:
blah
ResumeBuilder.rb:85:in `+’: can’t convert nil into String (TypeError)
from ResumeBuilder.rb:85
/projects/dev/ResumeBuilder $

Line 85 begins with: correct = boolean_prompt("You worked at " +
comp…

I’m really at a loss here. I thought that each company would fit nicely
into a Hash value… I’ve been banging my head against the wall for a
while
now on this one.


Samantha

http://www.babygeek.org/

“Beware when the great God lets loose a thinker on this planet. Then all
things are at risk.”
–Ralph Waldo Emerson


#13

Hi –

On Thu, 1 Mar 2007, Samantha wrote:

prompt("#{string} (yes/no)").downcase == “yes”
if correct
puts(“Great! Let’s get started, #{first_name}!”)
else
puts(“Please come back when you know who you are.”)
exit 1
end

------------When I get to this point, if I typed in the answers to the
prompts with the first letter capitalized (ie Samantha for the first name),
when the program verifies what I typed whatever values it is verifying, as
blank…

That’s because capitalize!, like a lot of bang methods, returns nil if
no change has occurred in the receiver. So David.capitalize! is nil.

puts(“Your skills are as follows:\n”)
tech_skills.each do |skill|
puts skill
end

It’s much easier than that:

puts tech_skills

:slight_smile:

#This section gathers experience from the user.
company1 = Hash.new
[“Company Name”,“Company City”,“Company State”,“Start Date”,“End
Date”,“Position Held”,“Job Duties”].each do |input|
puts("Please enter your #{input}: ")
company1 = gets.chomp

That’s wrong; it should be:

company1[input] = gets.chomp

since you want to set the relevant hash key. Also, make sure that
there’s no newline between “End” and “Date”, as that will cause
company1[“End Date”] to be nil (as opposed to company1[“End \nDate”]).

correct = boolean_prompt(“You worked at " + company1[“Company Name”] + " as
a " + company1[“Position Held”] + " from " + company1[“Start Date”] + "
until " + company1[“End Date”] + " and your job description was as follows:
\n” + company1[“Job Duties”] + “\n” + company1[“Company Name”] + " was
located in " + company1[“Company City”] + ", " + company1[“Company State”] +
"Is this correct? ")

Consider a here-document:

prompt = <<EOM
You worked at #{company1[“Company Name”]} as a …
(etc.)
EOM

It will look more like the eventual output.

David


#14

On 2/28/07, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:

blank…

That’s because capitalize!, like a lot of bang methods, returns nil if
no change has occurred in the receiver. So David.capitalize! is nil.

Ahhh, that makes sense. I tried it both ways, capitalizing and without
capitalizing, and noticed that it had that behavior. I don’t think I
want
to redefine the bang method (scary scary scary). But, what can I do to
fix
this?

puts(“Your skills are as follows:\n”)

tech_skills.each do |skill|
puts skill
end

It’s much easier than that:

puts tech_skills

:slight_smile:

nod + laugh I’ve done that in prior little things I’ve done - Donno
why I
didn’t do that this time.

located in " + company1[“Company City”] + ", " + company1["Company
It will look more like the eventual output.
Thanks, David. I’ll definitely need to digest all of that and try using
it
in different ways. What I’ve been trying to do, is if someone gives me
a
suggestion, not only do I try and use it in what I’m working on, but I’m
also trying to find another way to use it, that way it sinks in a little
better.

Thanks for the response, I really truly appreciate it.

David


Q. What is THE Ruby book for Rails developers?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black)
(See what readers are saying! http://www.rubypal.com/r4rrevs.pdf)
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)


Samantha

http://www.babygeek.org/

“Beware when the great God lets loose a thinker on this planet. Then all
things are at risk.”
–Ralph Waldo Emerson


#15

Well, there’s always more than one way to do anything,
but here’s one late night hack :slight_smile:

#!/usr/bin/env ruby

class ResumeBuilder
def initialize
@data = {}
@fields = [‘First Name’,
‘Last Name’ ,
‘Address’ ,
‘City’ ,
‘State’ ,
‘Zip’ ]
end

def prompt
@fields.each do |field|
val = @data[field]
print “Please enter your #{field}#{(’ (’ + val + ‘)’) if val}:”
val = gets.chomp
@data[field] = val if val != ‘’
end
end

def confirm?
puts “You entered:”
@fields.each do |field|
puts field + ': ’ + @data[field].to_s
end
print “Is this correct? (Y/n)”
gets.chomp == ‘Y’
end
end

resume = ResumeBuilder.new
resume.prompt
resume.prompt until resume.confirm?

I didn’t bother with the formatting, but you get the idea.
You might also look at using a Struct.

-Brian


#16

On 3/1/07, removed_email_address@domain.invalid removed_email_address@domain.invalid wrote:
>

Lose the !. Just issue a new string with capitalize. There’s no
serious performance or memory issue here (unless someone has a name
the size of “War and Peace” :slight_smile:

Even that should not be a problem:

“War and Peace”.size
#=> 13

:wink:

max


#17

Hi –

On Thu, 1 Mar 2007, Samantha wrote:

name),

Ahhh, that makes sense. I tried it both ways, capitalizing and
without
capitalizing, and noticed that it had that behavior. I don’t think I
want
to redefine the bang method (scary scary scary). But, what can I do
to fix
this?

Lose the !. Just issue a new string with capitalize. There’s no
serious performance or memory issue here (unless someone has a name
the size of “War and Peace” :slight_smile:

David


#18

On 2/28/07, Samantha removed_email_address@domain.invalid wrote:

After taking several suggestions, I’ve come up with 91 lines of code
(including blank lines because I like organizing things).

I’ll post all 91 lines (including lines intentionally left blank), and
explain what I’m having go wrong… I’m just not getting it, but maybe I
don’t quite understand certain things… (probably, not maybe :wink: (And
please excuse the rude prompts - I’m not really this rude, nor would I write
such a rude program for deployment into the world.)

Samantha;

Cool script. I like the prompts :wink:

One cool thing about ruby is that if you put key/value pairs at the
end of a method call they all get mashed together into a hash. You
can use that to help with readability. For example, many times in the
code you check a boolean condition and then write out a message. You
could try something like this:

def verify_info(ok, hash)
  if ok
    puts hash[:next]
  else
    puts hash[:fail]
    exit 1
  end
end

Now the messages can be passed in like so:

verify_info correct,
  :next => "Good, now moving on, let's get a little information

about your skills.",
:fail => “Please come back when you have some goals.”

Or even get rid of the “correct” variable:

verify_info boolean_prompt("Is this correct?"),
  :next => "Great, let's move onto your experience.",
  :fail => "Please come back when you know what you can do with

yourself. :)"

In this case it doesn’t afford you too much, but it does get rid of
the repeated pattern. Say you wanted to change the exit code. Now
you’d only need to edit it in one place.


#19

Comments inline so I can make sure I really “understand” what’s being
done
here…

On 3/1/07, Brian B. removed_email_address@domain.invalid wrote:

           'Last Name' ,
           'Address'   ,
           'City'      ,
           'State'     ,
           'Zip'       ]

end

— I’m assuming that here you are defining the class that is
ResumeBuilder… you’ve got the @data and @fields that are instance
variables, right? @data is an empty hash and @fields is an array…

def prompt

@fields.each do |field|
  val = @data[field]
  print "Please enter your #{field}#{(' (' + val + ')') if val}:"
  val = gets.chomp
  @data[field] = val if val != ''
end

end

— Here you’re defining the prompt method… and inserting each item
from
the @field array into the hash… then you’re putting the answer that is
given into the value for the item in the hash? (wow, that’s a hard one
to
articulate when ya don’t know all the lingo" and then you are ending it
if
val doesn’t have anything?

def confirm?

puts "You entered:"
@fields.each do |field|
  puts field + ': ' + @data[field].to_s
end
print "Is this correct? (Y/n)"
gets.chomp == 'Y'

end
end

— here is the confirmation section… You’re telling the user what
they
entered for each value by iterating through the hash/array?

resume = ResumeBuilder.new

resume.prompt
resume.prompt until resume.confirm?

and here you are defining that the variable resume is a new instance of
the
Class ResumeBuilder… I’m kind of lost on the last line…

I didn’t bother with the formatting, but you get the idea.

You might also look at using a Struct.

Will do! Thanks for the input! I’m finding that this is a really good
way
to learn.

-Brian


Posted via http://www.ruby-forum.com/.


Samantha

http://www.babygeek.org/

“Beware when the great God lets loose a thinker on this planet. Then all
things are at risk.”
–Ralph Waldo Emerson


#20

On Mar 1, 2007, at 7:02 AM, Louis J Scoras wrote:

You could try something like this:

def verify_info(ok, hash)
if ok
puts hash[:next]
else
puts hash[:fail]
exit 1
end
end

If you keep doing a lot of this, you might want to look into the
HighLine library. It gives you the tools to validate and convert
input as well as issue error messages on certain conditions:

http://highline.rubyforge.org/

James Edward G. II