emvee
emvee

Reputation: 304

Ruby script to read file line by line and do if statments with puts?

I am trying to write a script that will fill out a mapping of equipment by using if statments on a text file.

Here is the code I have tried:

input.txt:

SWITCH
ROUTER
FIREWALL
ROUTER
ROUTER
FIREWALL
SWITCH
SWITCH

Ruby code:

IO.foreach("input.txt") do |type_equipment|
  if type_equipment = "SWITCH"
    puts "SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch"
  elsif type_equipment = "ROUTER"
    puts "ROUTER,BMC_COMPUTERSYSTEM,Network,Router,Ethernet Router"
  elsif type_equipment = "FIREWALL"
    puts "FIREWALL,BMC_COMPUTERSYSTEM,Network,Appliance,Firewall"
  end
end

The code runs but it is outputting this:

SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch
SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch
SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch
SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch
SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch
SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch
SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch
SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch
main.rb:6: warning: found = in conditional, should be ==
main.rb:4: warning: found = in conditional, should be ==
main.rb:2: warning: found = in conditional, should be ==

I want it to evaluate each line in the file and if it matches an if statement, then output the associated puts.

I have also tied the == for the if statements but it only displays the result for the first line only with no warnings.

Upvotes: 0

Views: 474

Answers (3)

Cary Swoveland
Cary Swoveland

Reputation: 110665

To make it easier to maintain your code when new equipment is added or existing equipment retired, consider using a hash:

hash = {"SWITCH" => "SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch",
        "ROUTER" => "ROUTER,BMC_COMPUTERSYSTEM,Network,Router,Ethernet Router",
        "FIREWALL" => "FIREWALL,BMC_COMPUTERSYSTEM,Network,Appliance,Firewall"}

equipment =
"SWITCH
ROUTER
FIREWALL
ROUTER
PINGER
ROUTER
FIREWALL
SWITCH
SWITCH"

equipment.each_line do |l|
  equip = l.strip
  puts hash[equip] if hash.key?(equip)
end
  # SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch
  # ROUTER,BMC_COMPUTERSYSTEM,Network,Router,Ethernet Router
  # ...
  # SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch

or, if you prefer:

equipment.each_line do |l|
  equip = l.strip
  puts (hash.key?(equip) ? hash[equip] : "***What the heck is a '#{equip}'??")
end
  # SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch
  # ...
  # ROUTER,BMC_COMPUTERSYSTEM,Network,Router,Ethernet Router
  # ***What the heck is a 'PINGER'??
  # ROUTER,BMC_COMPUTERSYSTEM,Network,Router,Ethernet Router
  # ...
  # SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch

You could use String#chomp rather than String#strip, but I chose the latter because it removes any spaces fore and aft as well as the newline character. When reading from a file, you will want to use the enumerator IO#foreach.

Upvotes: 0

QuinnFTW
QuinnFTW

Reputation: 554

main.rb:6: warning: found = in conditional, should be ==

The answer is right in front of you.

When comparing two things you use var1==var2.

var1=var2 is an assignment operator, it sets the value of var1 equal to the value of var2, so your code should be:

IO.foreach("input.txt") do |type_equipment|
if type_equipment == "SWITCH"
  puts "SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch"
 elsif type_equipment == "ROUTER"
  puts "ROUTER,BMC_COMPUTERSYSTEM,Network,Router,Ethernet Router"
 elsif type_equipment == "FIREWALL"
   puts "FIREWALL,BMC_COMPUTERSYSTEM,Network,Appliance,Firewall"
  end
end

Upvotes: 2

Patrick Oscity
Patrick Oscity

Reputation: 54674

  • Please indent your code properly
  • As the error message suggests, you must use == instead of = for comparison (= is variable assignment)
  • There is a newline at the end of type_equipment which you can remove with String#chomp
  • Conditionals have the last expression as return value, so you can write a single puts in front of the if instead of repeating it inside the blocks
  • I recommend using case instead of repetitive if statements

These suggestions would result in:

IO.foreach("input.txt") do |type_equipment|
  puts case type_equipment.chomp
    when "SWITCH"   then "SWITCH,BMC_COMPUTERSYSTEM,Network,Switch,Ethernet Switch"
    when "ROUTER"   then "ROUTER,BMC_COMPUTERSYSTEM,Network,Router,Ethernet Router"
    when "FIREWALL" then "FIREWALL,BMC_COMPUTERSYSTEM,Network,Appliance,Firewall"
  end
end

Upvotes: 3

Related Questions